From 3a0c844765bd0e37c9d0f0af3a2c90ba4f278a2f Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Thu, 16 Dec 2021 15:25:17 -0800 Subject: [PATCH 01/10] skip unknown compiler for BuildWithSecureTools check --- .../PERules/BA2006.BuildWithSecureTools.cs | 23 +++++++++++++----- .../Pass/clangcl.pe.c.codeview.exe | Bin 0 -> 696320 bytes .../Pass/clangcl.pe.c.codeview.pdb | Bin 0 -> 5373952 bytes 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.exe create mode 100644 src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.pdb diff --git a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs index e4d7a3073..e3bce0d4f 100644 --- a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs +++ b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs @@ -116,6 +116,13 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte Symbol om = omView.Value; ObjectModuleDetails omDetails = om.GetObjectModuleDetails(); + if (omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftC + && omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftCxx) + { + // TODO: https://github.com/Microsoft/binskim/issues/114 + continue; + } + switch (omDetails.Language) { case Language.LINK: @@ -153,12 +160,16 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte // break; //} - case Language.Unknown: - { - minCompilerVersion = - context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.Unknown)]; - break; - } + // Language data is not always included if it is only compiled with SymTagCompiland without SymTagCompilandDetails + // https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/compilanddetails?view=vs-2022 + // Compiland information is split between symbols with a SymTagCompiland tag (low detail) + // and a SymTagCompilandDetails tag (high detail). + //case Language.Unknown: + //{ + // minCompilerVersion = + // context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.Unknown)]; + // break; + //} default: { diff --git a/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.exe b/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.exe new file mode 100644 index 0000000000000000000000000000000000000000..5ed9a672189860a5aafdab045a50eb1336ec1d34 GIT binary patch literal 696320 zcmeEv3w%_?_5aNa76@$6M5CfcjTXy86jT(b31u}>R+C74KPzC2FDi+mB}!akv#hIF zrM0bXRqXF)TeaF&h!!y*5^S-eqN2qb5q09mb}LZ>uH^syo|*gD%?3p9@%w)YpPRjR zX6~6YXU?2CbIzH$!Lw&u8J1;bf;yL;M=Usi~$*gEbDBaWtC(~@`8QwlV_JG(f7#eW0LG&E8gE}M3z<3AO+<;{4wu4 zVDRqB(fzHVHrRB(_w=_e3|iI$NA|adq{}yHg)@EDQcwQ)qx)OsBxo=HM%GTBU5mW# zv(QE&#I~jozsRyK9C`J$i)ulcyWa*d)M0JH@A>%k{3`*KM(Sc#`Toeb5H!fe??n81 z{*_o(%g9lqE}n6TWeJ42$R~ME=~1p^qJY5BEg1M0@-;p1O^NU+26=!$j zUwBHf5BKDCD?F(3=*AO@011jORRuS3ikr5zZl?pHKN$!H4*PEbI_yYv)8D+|?Edw1rlVI{$)m zh#cA%&B?2oY#B`PEcg{ABL}oPT(nvN6m>`P!d3AIxEL4#mv{;;gO6hef)k`7)BbS- zIVS2do^C%Fyn^~89St2rvMj4+@9u)aV` zd$f;#CuHOAj9Usu$+E?`Tx36u7?F-fCTGtE=)#q7teOm(}I*>HzntqTkq4tb0rA%&UMMk)Q zbZ8bDtj75Ag>NSfjBt$giv$v(7BFfe5=@K>=FTdJR3(tc5ue=<&R#eQg=4R4l8xk; zOClNQRpV3de%9Ts2`Tg|PNrYq$3bc9tLBgmpkQlGHL%aX|DENPR$&z4?NF|OBOyF> zV3(vUZ?hr;Ev8J#>C)7p`jbo@880vW1jsNO8Cj z^iw`iS?$R`q<2k*`UJutv@+YjxTUeBu5V3W^%IDSe{572_${k??qMaC`VA%SlxCIik^LhE_xHQqWn|FKbxWJl&k&E%@R0=BFVpab>p+O zIqFitRGomKx-}p|&j<9;E$2N=e9uH--cw}oS+VRL0x!5$;5p5c{4&Wp>c=TrB60Zs zU5{ir1i>>1u<9AREc1uT`v*=g^rKWws0&7-LxPF0&+QewAL__eRj7g` zJ{W-#xa(3c@y-_xV#ZHYMgm>sm?10FL!WeahgRk$y7=1|{_%cYgD)62?3RMmYGzH!bO&D_p__eMd zDEvnhiCv^qth%YKIg$mC)%TA^?M?Wjezlx5@S$_}Y7MOJMka>!HcI=z>h{yXJk|49 zb`HxPtjlURWb9ZrFv##P4!&EVUN-zQ5Tp$U+9FkLq2sOE(U^M5)o~~+$det4kQK=c z2UgZtHJLS_?#gg*eI&TPyTF<|+3K!ZuU;48Z-`WFAc%t^feq#AW1!-I7=)}yX1Q8k zE*+>Y1;XLLI+cOCh3D$}MXJ_Ss<%$f!gJs~@O+M%io&QeL;YSb^+kf~!oe1&wJot~ zb051PQq_U!7hSm)cj(Hs<*JWv`_qx>P<+;ggKN~Cz|y~XZR3lmEU>0r-6@p?-)npp zmGwnsk*YP}s-;c^OJfkSnzX_Av@p2evd+5T{BvB+&|FCVtj2IvFKLm;XN3;2M*yBH zC-qsO!AT9A{waNJA*=cI-V(3{bf!>!XLsFUm~Jc7=0!q15XVQEUX_s7 z2?wvo4v&3{wN&#xRVGEjB`6AAHrU0YUAkzOQx=CZ z+gs}E;uxuBIi>CsE)+<>ciO#$fNdI#XN;G&9^++w@8gBjbYN|3U;~ze_5g_lH&m!R zdla$T_B6wX+&(|>Ui{WqH8K&3g2R6kfoBLR)!(yu&>R0DrIa-HKTn8qX zPF#my^uju_+p56ZF37ic%tX@PKD7{%9sQMkR7>nA^#Ix!DaqDT^b=!2^3g4E|D*jO zwnFt?R_!44__#nQq9N(Ddl3) z$%POhqC@+IF9vyuWG%EGUj`<-9M#An zcOgtIC~}lEV7TV}j$fN$QcL`9)C~J-QesW)0(7hlJj@lrI3|E_RVQc)`cg|C$UzjT z>I@f5;!U7yQ5k<(c9WDaFdwHQ-TAhZg?2Us3|?5N5`S^W9zlX$=#f?67?HPjmpL6n zei$p2)%I2Yh7gSHp{l#OyFoV+sIU4V9y}eu@;+VOuPJ)GCSGiiDw>={q;u2~+<3;j zr4BnldQ~mk+YtnAdsQ=1U2fW26{55e{Awxkyo|*9nXeWh!-JOr$M%Lg@}$R!f0YOi zs~F+PkLhpTFIS(krF1y-M3(J6Tv7!oG-xoq{&EO1g#MXKTy z)mrHusylUDP}LqHN_XzKiMdzr1w11auwNvy%6-RG<<82%Eynel(cW?GX@5n-1Zt+I zyj${@+99HY9143}cWquo)^4A?fY}Q9vB~OG3>?(iP@iC7%B;kxxQPux?F}3GQr%!w zHgNDsmbJVsZvck?$rctsDD=sT;R3>P2_p2!AKe0Sp#4$kOx*=-&}%tfWF0YDc(=RY zZX}KtfZYXmI``3F2VNLU?YJs2x~ju|2UZnU97W<^!=Q&VBceWA)f5uoxtVg;7CY(k zF^z05KNVi}nHaL&1wK*B0Z*P)7KA87B%PR9G|(AT+r$M z2~?9IpnOt7nrF<%Dkn}IN$B7UJzI=LJV+9zVMpyNol4e=3=aJ@Gg6w3+wkBpexXDF zUUN0tV^@ObiqM2y^r0pFZ_inxfw*M0o5%6hT$}uU^X%m3)|@#=;6GG?@}Z8hnn^WS zt2dXcEA}GQa-+d!bn{x_i%p@88MXcVOJMi`UsJ1s-e=7)b<6ucE}2?T8YQ5DSTgHO zLka&9U&9t>P*=*JNn}kNuZLd4an5i)Hd4ibSLhDoLpi{&s~vPL#YEu~wBlX1Vh|JO zWX#qzB#(4W0^pO%AL>j`FCxEs?V%-Ri6``K=ok(iwTFGACQCi9#d7r;Xw)E3<2uYb zt0fAFJixCuidCj9V7oEkDr(^7G5f<)^V)ett7e zejd6IKX>2Ocqe{Zr4BBDBf;!&^cEyVtFprj@8V4$J5rViN1Je8Qx1Hp?x|Eu^97mK zz&*gKq&09q86*;b^6_AIK|Y2=s4Jtc&#FK-R1N&K<_Ei*g4^&aOiQ{!kOcOMHyVti z+qvRJ2T@h2+XJ)yHfV4CL5=087bD7*C8T&7dW${RM}*I7Bm0){DXK88J%dDoqsUzVZvn@tK?^xT-9sndlU@Afa;5sWkVlU zuSil?I8U9sA`99Ta9WWKYuB1Jr!V_6bl1qL3H+J0{~3|*Gyr@*1133Dl6YB5LqDk24Z z;5-pbIO>qgMtC3Vdtl4?rWwq`b@b6ha*8qRrkL(<7S!7mSs|6J%-&`%!}G$_9@ zGlK4G^bmI1m0Es|Q+{tLf45UUxt*T=^pZ#V4?Y4Hfng57qXppi9DqAT7f*eV&!Q!a zeg@+8w9{L2<{9yQZyu%v7_Arax2C^s->vIAx~2U+h^*E?96d!Y(Lcfn(Ym(LEu)|H z-xux^K0iBriZ6V6u48bWRL~X2+tFXd5 zG=4(2e?m*246F7um?|3H;&a263;SeRwG$&%>l-#o!q%BgIMR8cyib-@dvMYVNEn>- zLY7rG@ZKiSk7VPoX?m7pHJl0(OdS}P=NH;sQUFOLhw4}Nom0UU^#%4REwb&5Hfg5n zckE;~6f0MBOszjsAV~Z*Gb}f{Ps!(|Pcx-Y-P#Ansqf`k{&~45rHccQT|7H&am(kQ z_XY}i5QxjtInO`u8I69%TCBdqRj|CQf#D^zu}`QCV-?!r%20hvAAjSoP%Kox((*Un zi91~{CQF!7h4-HIh2=*2@`a6&Nd@sxTT$(0x?ql{U{Q~PP={4M zpKjrZ>0PMWh4Bmd0Q-kEA=O?O@7?|(OWUy+>yGjEk!wk%_sX7U(os!kI_b&=uPQYGdgA3|Sp^>Jn62ZWzy{9@-d( zM-EgAEk|jr_kHR~5R)E2F*K@j^_*UgV^!Q&WE9qI4<@bKqHQ=6v=0gAh?8>>-h z96s$|t582(3PekasUO3e0}Qh<-%0bKvm_$EaY0{Q_GqluV{b_<9xf$4&&2DYmOPnP z_*^E>`OfoLc`me{MgO1^$YUmVI2i9^K86D2%hC#1Zs_`KYYwc7xgZ3&C%Zo#+7&P@ zCbDw#L`fszvnGPRo`su%DDB4r+1E-wwA6#_lQO<0?K=zI7nwK&Jp)sxRXbVePDTU2 zCnE5pq7%4s4=F&GHBUzDTQRPlu?9EuQ#8;~UTs|p73dG5VT#c+!}NmGFPa}a9NkT0 zHdn-z-~Db|?O5CdPsPmIBcyI8>Ie4sXt~)FwQK zW*1sF6sp&F+XDA6tpkzFkjg+S!ayLFnZyc05#R%2ELs48V)qC1UD)ZUa!do+* z2!jfcS%g8EW^@q-M%NX+*XX(w26e?MNHjs5a*wimoTPPy%k$NhON_Sb#zScRYkT^q z*2m$v$`!?4ciaKwQ+7^GCXg*xo8VD^XM#)7U?R4`;ZWV)ae-W6VAwixL(6k0g+eQG zD%GtZWm0&CmIu&JJD>UGkOp+{9azgi67dOi3$^5c4LC?(yn)M;9qM0}3DOlJ$-j8; zXfj6P(m;amaXh_DKJo~4;fF~8Rjyuu2!tXDx4uX+4AM>Q3>%6DyVaqPgD@gTgWJ?r z%#(0eR5RQP$^md+S6M?L3uLg0QrB-~8w$&#SXcZ?Uhh)J;2mw@+PgKdmWDPjHTonp2Apbf9z8d{vxN0Q~U~~rgh}k7*P&ph$FkC_=p8OFj%ms~tialMa zs7!Lj8`u!4-yn0whH#*Th)o2kd6X_=sJ zw~wP11xLQff}98Jf`G@I(a);;P`%hUSYLDb(Is|$CjXB~`7_;o8^0aVw=@m8^!S&V z2XxUQJ7Fjbf~WR|^cUn4C4ti)KO@|)u|GIHV%`Yk(Pxv&fOdar`airj4gE#n!?S9PJN%0ihWOQypgYCZDpEa0mO z|15TY8qyrUf(;V+kb#RIV>{sHNo_9sGbs(vdOit_-Bt@59p*c#7Dkbvq69@k+l?{9 zs4M<~F@Qo)H%uvrd|fJ6EX~vj)JZI*c|+ijp{2?==)kQQr)tb0K4OTM!ytWbNI_ZU zyW#`D#N8E{m^V5{B0ebCIw5?Z4xb{6arR}o+M^{~AP}4E(8d}5#u1cL^bD+l>qgwq z2z6T%o=Agiq#_^cW2_HWmrx%N@3qZ8?^E>KWx+VOqa!-0KLQRFB%~;Nn;_uG?eJP| zf)@Xra4?kBO=`$f*_eIWXn+gVw^{Xr(JbUz?GN+M{rJOV|E)jA9U5n>Wn)7V)?o&) zYLBSqueuq`g4Sc6JfJ3n<2N#p>EYl8I9hFeeS@CAq3i;XdV5(mM^R*A{7ge+{jw6UID3 zdjh%L>UI=lJE0791JgVQ+r_C;Qe%qh-peAYj2Ji6u5mJIw0 zZ7K5K{3a;Vuw^d(`frNx?-Pe|?VK^I-{#*%CKYE#wmyv{E=M!`p+BO)4F8oaGyF4K ztgPq#gZqYB^Fr^%hdr-BTr(wle=*8f=4ZhS|BZcdos`EvMf@|0e@ghLoPRFlpPA98 z=HjJ>cK-cjIUFzDb3rVdnj5cJ4+Ot1d4p(1yZIRuAUm({C_YI$v z9cuN3+I>2|?gIliDQD zZPu(wTRs&YBnX7gV9_eFn*!aOg-^p1hcu!T)T0)sDEVZ`>L)=byZ(|&oZ;% zg`hwPqRb^DjrdB#Uu-`rTe&s8{Z;U-7~P_=sCazd91!PN;9|Upl3$Z~?;}VrSIhn? z^1d~PkNgKYKk(1EN4$ld#YdA>@CX>SQZ?CGeAHR@{u#IB>PkC@kNoGMl&Ak{x>f#D z(nMNU{AkY0f0Re{1_XD~JA!X@`3zXL9t0w4X$nxCf6ouftm-2CQBx9>EN*~xYJNw$ zeD;62`oSwAl#;5~{jXLb3v22$GmgMli;=J2lV{5KVD3w+G1JI%#r%LhAIP(#A#g>& z6}ITH@Gf+PR%9Pnm4JaC+6MKN*ha8`tqYNY8Xjk4OHq+0%XqaACtv27&|kab{^f%w z!*oM)&ZvtfTebV3k2%d%s+QH#`^ajwn3YnMbeO=a>8`%#+%hNF4DmUXz7l5EIc*X9 zndS(3pyO;#T$+P8h7M^?oB<+nSdp-E&HNd* zf&eO%wrBhF)M(T9vVd=FP7zQ#?`e4-7I-mYrSlq?bxqx2)$7SL8v;jlZYA^NH?v4AhzYAQ3Uz^#qS%u1 z_|(Fu77X#+FecAD#E&rbcSwy?<%Kgt_4!t<6#S_a1P|qN*`B6<(PdaaCDbW=ceT1i z$`@ftJe4lap8Q~!M<4^sAM2DK%Ee62^58F<15;Kc9{x&1l3#WC1@Zf#33pKh)aAD3 z$PFY=Y)_q-Ro`DHa+0VyrTPJOL1s<%y)0O+=C34I=F9r<0BSU=)fxC%bT@Lj;`%lo zLKFC8)m3@`o#p_F3?!rqRpLPEP*hR?X`lCx7C7CVP~R4Q{o}JGaxFO0^48#-G)G=L6=o^jcvVY6kt;& zX|KkgWQIuUk2EVBHy`YB0@{$&+eV&D>+NCY=!#lX%S(qIl>P; zo9B_2dWEw_zW^#|sVew2Hv^bn7U<`tDbM$(JU@{9Y$AZt8swn^i0Ao`>IWz+w7jVq zUAljf9y({_9iqrG=b>JQoa-HEg^uN_(hi> z28O!6Rd-1BT?AliA7j_PtRSg&6da-cdW5HTT~gOh2rAc8du$*lk^)U^|W zN_4ul8+x$zWO_6|h$Jt6QE~D#dR63^fV$O&24={XD%QB2)#lL7;B;)-s}|X zkt1JnH3XTj0O1ut(x}nuE~eN6i5dgi7;eZ|E=W*&CD`R^IfAbzB1WERp->wk8v!Gl z-QX2*lE16^)^_xf+>fb;r|2We5r$_+>Fo4`h|j>4U##-%uchd4K&4 z>@L(G5<;R7^yKas-);R;*yqQfC+O~}n=E1APgnBUff?wo@J)6J-Cpolcfljnt-z!(Shyy9C!dKvL>rx% ztWin6rw8RZ)G-{}`JmyfQ)}P=W-x6OR(yorfXO=Gb!=4-_@Z=;|^hmhqy;ZyI z_rRO8J$M&DJ9Xi`#iE|3q=h$pd+_`cFKy#@`}W}tk@jwY6Fm|vGVLuyd-KuWJhVL* z_vpWI&{0Dx;enGjPe_I7(oe&?Wk>M-0`rIq?*kV1w%LVOB>0UNc*O?4A;75+_~ipX zPfX0U!w9p;;P^8yOc$QUuLCxZ?Y1{E+KXS%3yU4%!qfb6x4`R#U%Dkm)b0-$9g^Fc z4&IdQ!TZA=#Lb5HD2sY&mkwTn1E@ECzCa=kZFm=LAD*V)g92|m{4$`>OTU4sFkSj- zc<1g2-rr!>a{1*+7WcN`A^`%vW?2ELwU}^=a~A5j+rmadeRqKo?D?1^bcwnvxU?z z!Y&gNcyIHKcRfmPbgme+AuR^_^g^L3(KHcLA?31!F-YA#>X&$v1m+)zasT29cmhA@ z$M-$^>r8*Zqs(E1zihS%;+6d{>2KTLiNgmg=2M{qw`n)8@bii zwPN9Dl~y|z4wN0CUOL28bKSz#)p$eTs6E~nO;#e$pWpXw9lpA7<6W zs)_mFZ5X=>)jPuGxGhpJ8S33M`-0{O-O-`tWjO92PhQQ>hz(VZ*axY%%MD>K5A@0%Q4}g<6p&95Y zDSn_PnrK2zBW)2(fEWzs6{*q46O2shB2_A-8PcPUkVnZlIZY z>!kLKwXpvKSnUmTWn<6zKVg(hBI53VG5Ev1h0PubbspeG5$}OY)RA}#V>VHt&VZ)@ zO1VV9zyjY17aJmAf^oj_J-opvDnnLp{r<&eKKLuKKNM>a6or_x=rK!R^Bc+wTY1W3 ziFJT93l_Zuw>yx-eZqrj%Y#GV!V(!}Yp==uHD6wH^HSv(-bW}8%*4JhoRnTKxg+ju zeL?yc`xO?K!39;jCs2!Ijtlr0(#mKCkrxs^J0A-z+ZK{qAE@e6ky8-6?^fn%fA97` zGyZqAy}jBOv3bK6>KauqM!WtTh)WQnxaIizT** z&j$0ZQ+ToiAnq1sc01#7bR%Z;w?PlF0nB8QfsEVsECJvTx?7sr z?axRKno|T7TDOp{R}J9XOw*v5-F}w?rUW8Fm!4+>n9QUB!c5GKU8!NTL8jH`z{ngs zPh;>t6LdM|#ZHt~77Ry|3XPpr{Ko>4$7R#J%XC3RUNXrA_Ual_0 zb|PqSwkjn11`lI1D%A9UOBPHvJATbED_ku~)aw zwV?3xALL@g@@za{VyNLvt?qlBg5F)JYl67)3j+QrQ-tm?*^Xm07J18K9~OCLSD-HC zTlTCh@PLn5zar$XQVo^1!C=u6>Y9$Nm7qC;0}+G3ITYz2$Rtx{3HOq};eGr4f00!B z?b$dTfNy8Y+rIgkaO-Lt%1yNVGSJyKKck5bJ-Z4iv<(UKtGb&8&kt;qSA70uI&u|J zf`~)(iAnlJrxiWs4=7YH$wY3KS~BPRnu6V^N{2S?1KJf4cZ-i9l9;;Vgu!EE7~3I1x4P)4Iw{H^ zX!{@eF?EL35kxCau%^-$IE7g*yv^-pN8w7Lv`W- z`e$$blc#_B=^`dncR}Ku5-SU^`{Npns}R?LxDLZL0@um7#^4%3& zOb>spxF4Ym#34RK8HnQ-^E^)z3)OefVK8;Jvv{aExOz68;2Vv8M$O7uIiTQpSV+_i zm^Bdh%Ogc)b(qoFh!$^^jzjV=!w zhuCQJNk(InRd*cGc(apeY#P6!5B;A-XY@w@ z`ZsqA{crv>i4AP}Um$20`cHJx=t2LF|7oMqJN-9anvVXtHJ^|EbI<#7_+Q-oJ?KB< zLl6B=1{d~5|IgmA8@_A&pNxi0|2O~R<$rWWul(Xf8Let=|=uMi_Ykc{`DJn3;l2IN z*QBF=?sK1y{%v0l{RfKsy@&jH_X7|8pG9Z%M*sTPb_@M)7N5I=hE4wq1Pz=2T{L>~ z|9TsZ-sykeN9pLl2B|yb|AvkhtOShGBg>IOt2Vc_@s>}!yG7IJukS_KkkoKv6Y@e& z@-Ho?9<8IA_Fh}@h>E-4Zn!BPfWt#w+<`7=oQ?OPenk1JO2Cehsv%H>To~0uu7fTl zO2~g+wTaMv3~U&p3n3^7=P3f!c|-*NVnCJmL^~pP;l{am4n4`gM74wfO&Hr99#l7O z*5Gv*n<*}+Hphr+E#4=p{8bCla|TrhhDMd()rl^uw0GdRmBs~lE!=pg{Jl&5-i^Nu zJdZL9KC|#b=C(F6mrbE|-iD=0Zs;v5+&C4f;pmwxx{&t+7V^GM2*AFYgD1X40`Q&$ zm@jutjk=~HIOc|k$_ALYN64LERUVC&-~}}pK`^+#pZ7d&%-q)CHr#j*QiawBN20tB zM`z-%De@`~Ka4aoq5W>u%caRi*!6NlZB}^U6qar*$KObl_XDE5_sYp<1K8q%;nJoGVH?(MFcd82oP~ld#Vuu z0b2y@DW~M(m|`FjBnpFLhdb!i`I(w8xJ{b8Eyl+rY%l9Y6bupkL=;Sqofr`ThnCb0 zAN?$*2*`sO;VI?YdPswJMzC2T4Mw7}XEh>H9C0E>VtWL_V^ZD~2+#b+2n3M_p^mYk zdZ++BydSU+x$)rMIe!pnY0vpTLkx$<=7D(d6FA{ty$Pczu$IP#wW{h}XZ$#?Rxfa- z`aWx&p?(m?k62&)q!`bG>D2~vSaq{!Zufgo>XVET)Nn!R&9{lt8ltpDt$4>l$$3?y zM5t=k^A1Y40&*l!1OtaY)UQVz(zU}gKmo?&z~p7sU-&p)&<9#$vdH7C*IoO)2KEYoGAQ{JPFFYLmn@y$I z4`P=K56_UsUT8P=49%EOL1#@-BlpleOs_s%&H2Mt9~UGKSFMK)6g=#vgQs!ufZKM& z4CF<*dy4vxBV3`f^Mt9NO9po3?5tou)r0F5?vdh##IFK>(4s4_614^*`;QUm@s7tl%>(YT@ckvRR!QggLkR3j=)?Q z%pVsl^xyn42Y0Z?s&8i%XEHPEJ zIJMy}_2|e9wD!+zEgviK7zzBjJre>42PG#pDkUEC)kEzTp`m7}!a1a_6g}O|93a#3r#*rrf|^E);8+hVWb#{&Uvw^qVyJ#y>g0EW zhYR0(JBbTX7V1HfYWW9A@Bm5hfLer}V4xvJjPt7ILYe%gwmMwcfNJS=o|DQXGNVy& zOjaKaWP8_o1jKQ{wG7ta7NctT%ZgpG4p;zg>|h`zPaS%ae~^Bd$iC zyoPQyxTcdQ^Ph2W-6L6^JR(pWd6I!Plim9bbLGja!gAY}CugO|lY7Z8R0%zEj3ZB` zsJ{-_IeGFzTe3u%j5+ovEsjKqttTmrMA?Qu^o;8ZuvgF{Q7k-Cq70x!`QdgYN~0rD zlGZ(`Lgh-S+z6Ehsk{X-4kFGr9?r@gp%TI)h03iMr=;>MJZqss1^9DnB)9heJYvP2 zm9<7v{ggelAnkWau-t0ghh}T6Em$sj)gxFYgR8b9SUyEu1y@t>0EdiVxgnKX9KkY0 z-HlMyoe?Z<+g**MdYRq+?TQu&f)M%A&{2rEr=IrXF>q<3`@|;6d)#7`%DZsmDEtjQ z$-mpP9|w)&(->uSaj_pA@(Q68;eBWcQT{3m+_fG1(W4UOD3t7JKORm*463{*+L1=y zg&T+BZ|F(>-JbpUKI0=asOsW^>g<;ZWeDCUs{B<|-~fYaI{Q%{7ggJSJQlBo8^_Dv z68Sp`f1yQ&qs$WfF>_lRnaidm+m93U^+zohUC8?Z3wiI_kBiM)v>)@H1eh;(O^v#y zboOIb4V$q7K=lI7n#BDSB&q3RXg`wM`M8Bi6{)uUnD^mmA^w^opFj>r8kvyBe%wjK z8@uo~66O7XDDRW)$Al>M<9yukp8@F}54ckW z920x9A9o0{aY2^%1ERe5+K;80wDx0zSsMGXVCl6V=O*K|><`>_lv`j1k^|F&8JmhnFofN4KAV?*1I z`QWi13mAw1kygfjoFW1q6o?`Mda)mi2v{g0pix9Xqlf^H{aC80Pj5dq=%uwEd$D!w z$0?#9SMU>2AogQ{m&ShVL(4tV;N@8)6cb~{ek_&I+)Vp1F%CyP0^v7O-W3Rqw;6#T z`asftmevvpIfdXrzlM1bSfaHAvCQb_V4}4YF~98bL@PGC@Qxc(3U$^HC#%S0wU!ji z9k<8~=Ub~Lj^Hb;C1afQv3xnSe7wqd88~@DQ(b+<;1_Bc<%v{GiFajCY(hN;foU(L zQr_2<!^tmlJ~{jkJVh-YUQh;7Ar-C&?pVm< zCJ8>}hxvVxIP6y3Ps5v}17Ql~WFcPi87qLG^$W&s)P%F=aSE#J z|4cA$mx0A+c`L`pWT`w4l_Lf*U!5a0bkuwsCq}9(|IYOYmIMe|4d%6G5V07%DB6Be za{|Hb%d|)o5sMe@52gj$d8zGp;+|BoO$p>S<59W^^9iR^0^K8R9*EX&irg65tmUU`+9;Yp}~2A-c3@#noA0 zD(Gf3qdTuw&s+|GgsS>4k!cG1#;~`iQ$>JLxmt+zz1{<;!>n~@+x%wsYoVj-9sKuT zzu)jUUYnhb69aHm*Rf0)j{*{KoQnX?&Psfsvs|6&%fu2RH`LYL)8k|IyYQ%E`R9&r z0P{Pw?N8Wwc5QxiUSx0D9EI=`Bn}NuL@@p$|s| z%Kyz%zIZ$3Q|mWh1#{@Vz5HedOMBw|n^)tg4bQVp&tF60r=utH8P*HiB)B3UT%k9Y zv!90j0E0}A8_F5MC)6>N@*&WbLxDxR9XG&n6Ih%2J^D-!VcBhT18fJ#4PA!=!ZD;e zAq&Jf$M_2faOc34!>Z4v_1VPb%KvD3KlhMqZ{w>p zB*T7Hn`9rr*#M^-1<`u77W8vT<^a$nTMgLihCezadknSn)Fs^PM*N`#<1UmY7LVrQ{^ar8YOrtpFLKlvas{3l==J{-jySS;k>P(BPX4?>_D%>yQb zF7&A`&h`vXBwePET?n{RXb zXSJt)t~KsK(?77NmZCDUbnqF^L@^5D6*`V#X$L@c^HTtu4cO|RkJxjC{VgOjKDnP! zYcS&kS5B!sjc+*WX;?0!7W}MXBPq0;0va>+#1Z6IwHR9xw7@a&iu8D2RYL7b2H(YS zQt+eIJivS62ytBV#Aj8hj{6JeDjx?$8!C6j1pL=pOmLS8kM6Js#wHcu9td<-SuXdX zm|KzSUE#@?M!NXjqOuXDHhq##iY$>Gt8#eLVbzzv?GnDtL-=jRz30l3QmNIa*1?$o zLB@g6rk0==46c}@9RSt${0CqOTTTB%GU1(B*^$?fnXM&7Xg>&MYpbmjwMxsZV(K=? zYAqcqg{aGp#hFFvdQIB=0S17*)d3)>{CYzkPfzICAFd`2}ye?7{~Z!%wEH!!Fj+VX9FLI$x2MUdbL zHH6yd$-LVLmems-2i7r6dPCk8_J{ulknq*!$a2>TlG9W(=cRGUF=fR zpQ9j8P)gT$VjVu$h7Ho8HeY0NHltHZJ%L*Tc&~N_^{@^R1 z$KnTR{$&*-LR(MqH*yOp$${7_9%3M$eS!B2TZh&T2&~heouHa&SY+c;}&4 z`mnacs+(?c$NMdPUEN{OYCV6s<9!k_2SaUoid?yg<9(BAT~6tPp7GJW=K!eoEdyA> zR&~EOoJeoP?qSK%+?5>c!vLC_X3J2PjRs43_T-wV$k)E=T%*^sud(+%$C|1xDj={D96- zZm?Z3)Ky)#pMDZm2VbIqszV`#*B~j-*4Bwb(P%b)Izf?acyn-Q>*%@>_ESYhXzNjR z2k1v^$HZ$Q#=&O%7`UZBdgE4lOdXbg8ik1&p{_A54v5Tkae$M-ik;6MoQNv14{}=V ziJqrRYsY$?uB!dE=cx|IPPp&QM)(8)>CkXK+4ZL!iTu zB0?STHYgH19Z*3Zs^fSn)8(MV@acG65?#-y;kqQ|CO(l;fJmzdo*?;1@qzlu%M6`;p%#{C<(zYA9kS6`%U!S5mXwfgnT=%@c>nqTivR=@0iIVPb`zkYrD z_4Bzx+>Ce3_i@qo0&zX(C`|34_e-_zd943O_X0UY_h8-`@-vxtI_@GH#Z?5PfST4m zmjx*AjjA_`4-XrKZU!Hgqw!P%p)1DKJkXvG&=uqAf6W7Q#khLHJU~~(_a@8(bj7%` zz)F0lkPmyB2k44%b&P(%5oz5}3HxHa{*VI|IZLt2NY5SoGVyes3jKUI4u@e1kD(sj zG6PHGrohKW=dMAA#MQy*53Tgo)RZt`up~g|#CZ{cj#ZO#I&mr|KCyu~r;gZ(oOgjQ zx>Orp>@vgLGBO{>)w50+*n9*|ky8eHc{z+jU9{jyXYaVWP2Qvj6$hej zlP^4O!xtX6H3dI)Uc9Jw59h^FmitT&PW=oAr+(HH*a~&}Q_NS`K3%mHEx~Lo7>w$P z!I`Om5&|f}^WGEXH5Eb+*=o|!G-)6XCd6sR*mT?>_NsWKyl7a(m|^^4?4}wvMZJj8 ztmjXhD<7BTBjma0g_|nSzN&b`3M#6ViXXee3AX^`t~Zlk=n!KDRkw4oi-zhj>#p%pYzZ7P?Z(JFR@8mS@aS#`lD7@N=GdLP%YpJ4prHygi|xDLP-z%>}xSX}4f zvIbQeFrcqhFkX@AT-CWIENW|H;rpLx$SlSqCgv zk77HIUfyzG@r(kg0ZWtk3`jo!*otDb)P8amTmQdyD`YWz`K(pJH;Awvb$)3_^!HiBqIv6u$TIFX}*C&46;Tp(qi$ zUfz1lc?;t}zFT3w4)_TSZEwnb+y$x8b6C6XR8Dxe&lQ_ciP+kqg1kc|?gcxKw zPCvhpi6)_biLGQZjOsWh8kuU8aP)#vuP=hAM<F+iKHupik2o5X5IKfPSwE`l=uvQ2MSMzCN zv7A>SYXQy>y2^?x^|;qho3G##Oa_9^%Ro@yok38|@Pa`F(DKy~;&9y9C^Tzz-dbt&DEZLLS|Ek5daX3@SnViLpGVZ~L%kxQ z5bLdpH_BEx$s2aDOQF`fPbWjIb)T-}t~jUUDRqPO!k!0ZAbnNI2qJH=l=B^~|y7o8oLqww`;&i!SxSKT}G{_>lQWNdE@3L#=)dte#5&f%fA2X{L@7 z{*m&w7rxjr9(pyUgbQC_MSIN$0kFoUW{x_cT|??x+BR~Q_Z>5yVZTU~?>8;?$~-(s zg=^mP%DmqrRsC$g91F&;#-E}Fy&ofG#|l0}2tARfh8$L{==U*J@0)>>?MRyXxUA;v zk1C+-Bau?VEMcp^-~?2}k6};_0&@82Ymd#L73zFA z#pDDc3{vw!I-Ee$_u6s{Ei4V^-B*G}(oQ&kVt!Lb`_n=_KF^3u%%2g?Xn)j6K?0ud zmFGmHH2-IKF`N;u$Zn4!O|Rg4J+|bq>b#XM9Ts@#Fa^x(*-W&Frcy`{tl$rRgml=z z75oO3^GELr-T|QLK-lU}zc6&b9K?xZc!p+stgG(5x5RoB*L%30Hov^*^%AZg`V`I& zc7xr-nH$ISH5TXN0Cqfd{TS;;Or*B9x&i8Al6s4$F%(xA(vY1S)B~FkQ1mb%da?epm7t&_~*?-jvc}<@v zKI;_4hy7IcV52mx57n=?>Ttewn}w760`b<8e9X+S_Qs9`p0;gxouI-Q&}hhQkfWSu z*Qu@8XVN}RUIFJ}GimrL(B3wonehX;PyZ0UV|z%@N5@aHFI69VPMyjbzrx)^2JrYI z=pjRFfS!CG&zw#iQp$yVc%msG`8>bp0?+v+`Dr}vZR#zM8Cs@3xT|Q+LHfL|>u)TS z^Sa)reXm0eU(($@za*n6usN2!DzF*CD!4fuRO(K=?EeE7yj8hbD@bRVVmj2Pi}3q2)e;On@Qo|^LMYZ>-KB)weG#hfwr#n`!)JgYmnG*0CW%;izu9U_^5-?j-%NTI zdm$vLA4n!?_eOp;bld_t?qONk5Ezkdl28;Y^p4?3CO?R%_qRXB4Z^aII5H6~`*8H` zPu+y^+wBA&6Xx*+%=l66`Aw>TJ8RWcY{t-=;v)+QyHam;M63xn z!2=_{hD3rv;sPd`&CDl*0nP1|xDCsJ1Sa7Fm_JPuj$#uePqXR9%kk`q)X<~a!(UK{ z`9(=c7js^20--@VU`_=6uV|;{(h_G?Tp35C0ym zl{5FF*^@;_=0a0utk8-~{b6B#&TpEIs7PRO2d3##r(;gn8m%8Z3(GurqveG&bcjvY z10wizh|K_0p;i3>h|bWlKM1ig5gIzgW^YJ$9b)qtV*1GHPKb@r-| zgqiYod`OwbNbTP?EVYxa^Bn)sS69Qdj6HBAiIk@%Y5 z-C-*NgE7X`Fkn=!rvK09i?7+=!5>z&ggO9?cH(O$FlECc=}>MSbK+~(Z{kuGXRWSo z*up5&-Xc@DxOB%ifc*i$G_@qY=8=V_w*Q~wYkqMmi3NilmYqf3l}S%|E%7y%dCLD^ zjIa4&5VBs+CtoDK<|Z*L>`Hvi`wu2**q->B7BIV`VK2f6F%DX+G~D=_QDF=$iLa?x zpaEg0N(a{%kV~HUnwOZAKE7r~BohXAZI42P4O~7Z!bY13D@H<@P3$nnW=X|JXmDNX z=Y>+YiLn_1g+PnD-5g`{C+!imC6On_CM+Vr#MoTUgB6^xBsa!J$R;s1``+e|ZTm4c zYyMCoMCCz{#&6Q4Hh`?gZ_=d>1T*mA1kwQ?_>_mE_<&D(%Y($&_@E3Lze$(6%sfbp z%_&$PBPTh=<_w0?0LGE2F*f@$14_OfV{-%$9FOZ{T&Lr@7}rc(^|s+ z_rvh27p1nb*`7a5{+AF>vZQRJy#`5*C$au0em(VQiHRr4D8P!;#FKoKk9!kO($0Gm zPx1!u`)jk)3%GaI*iQn?v$!6`^&4C-<9ZX<&c~B{`yS~+JD%i+_w^D_k_khbjwkV* zET&{{Jjpx1CJ+-((gmi_)2tIulJg(ze!@sf7f;fTvtMyeaGH3M=Ow52coI;%_jr;I zy9^c*s3q|v&r6c+qezV>`N5tLbP$`nFPFXvdR4dTlSBvUH(VQLX2f?Q4) zK0b^Et59$XZHY>@J8WnslgF zyn!a~NubGl2sC-GDYyx?EB&GbnwS?Q(Bxf-4|x}XChs-{-iA)O$po6bjfS1uJStto z3|C+bA=<=-EYRK&Xzw7}B=}ARqD@Xii{R>=;a|2kU1IS0I}S#8uxs7QzUr6iz(P-Cz|djUFhkjwfC#GKghE7hOy`BBtJH(G}}9b5(sL--)k z9En~5e+ne%0=0-<>7dSvf;xI-eI?wFfes0dDOWWb5Hv5b&d1JxpoaksevXRf66;&I zCgEztbu6y)aXpA@Hm+aex(wHkaV^316~>=1-VDwNYQUqPodKIyv?_tsTwG0go?bT+ zkbdR2g=gYwF`|52H~Mo-rR!uUXc8yuYVQgR+j*7h`U=thG?3|tC`mND#jU-ahdQ<8Vh!U4T zltX4nnpA2R;Rr~2O^>l@SCFi}b*0*%1#$2q#j1%35L1AG025yTY6*%tp|ob~cV zn5Il@zkoB6W_pAp!jZwl^k6@ZJ;4RLCyvGNmm9ybpNU_2Iw^kT9+}P(YJ#M4MZ!sL zK2yE%E27Su_!XH=K5zVrOgAQeMS$#F{K~2_@`pEm<$kRBdd9E(9jQP#P5esdJvIc& znMY}?;?in|@hc4P3 z0y0mU_?3Bg30IIwq+?9{iqPGOU->sQDlI4N_?3ErmnMEC`)3*+iIft*f^!fw@pd_W zWiM?=cmM#KXNl;CSS=liMu^;6i!X!Prs6TiRP5N#Yan71Du`EgWXenEQ?DaQo0DC8 zyDs%mYAF|95#c=t9aNhN-1wDtr0KW2AL>zu`@Y1lT=Bb<5^g@Fj0*Oe4|eP&eq|r; zI|47%ktTlS$9H&Ts2#s@x#CR9k;4Hk@hh)&Wm~%(zj7zG_<7b%tWo&dwLTMGafh07XZm=RNq9MJyvq0Z0!GC*AztOFP3R?$a~~Ze{JHb- zDmgy_q%SjGCHpOOhI}qzr{h(&yzRuR9DoM*7O!&C&1ixrUgfCCJ&0q|$M^$wC0?cI z^Tn$?CrckEUgZXP>=CchisWRDN{&}C`>6v7>}|KWjU+Mmy28HV28aBR^8jQQH3qi3 zdHT#hVG1yjkr!baw<9BuH*UtBo2T=dIADx(XEW4bQ557n00%(zUCjVX*y`R{wnVj^ zJ2rirq4RssPiS6Un>OC+*UNfzku#t7cAmmHM}St)njnlmm%sO%zZkPp-EKNhVe73) zGm^*OyA~Yi%t(I%F^vNy$=^HsN1&hhdoQ|L1A@QTK2PENrDk33|2oc7SSz(tm)Xs} z-d61fwEc-5U+*s)NiyT>ol7B<#@8z(6JPJhA2=j?3@j!)>|_^w>Uj#y&xz)uzOM5W zc!;uA3wt?FVLu=^6xY$XCgM63*SWYZ#dQrXdyX~w2I7Cj-@Cuf&AatHg>NCe(W7j7 z{Jo!rJR+eDo#l!I*WbH#F<4ssy|-Q^fIQ!9H~2FQOY8Vw=sblP2olu`6a%m4c?x?9 zrs>X8Xur-Z=y&2gg^wOXQ>lr4x#uZ7JU@x>kR|qc3iECv;f=HDl6k;JtCNr=?s*EU z{|&;+c?tzrCKKK^f4S>3S^pGa&~Tk(PXGE+&r`5o(EjhWw*PyV&Qo|2V4lVGD6Ze& zdKuT7xW0h@yFpmm@qdGFjH=z+c?yNY#9o)=|DH=Aw*MP_r5ClX|NF)5_`hH1)&DIy zz5BnHZSOpVA7hMYcqx{X9mQHo@||hcDv)7K-ee|NE;v zPhr{3spH*tF5h_r8Orv5gS)i(Eag0f$1vWt|GUPF_ucRRPDat||E~9lq;)rXQFQ&^ zKBB1o-y>rzf8$pnZ5)2jz;!aNS-5tC|9dCSQ@H$fnRmwH2NsNP`gsbMBR*fx z9kd_*_dEr-r@!&%Dcp64xSHW{-0^t|xexF9c?v^yebk?K@jQip9xRw^ReHfmua;Q* z<2oMK4{?paH5J!=xUR&t5Z6Vxns7aY>nrqUZ~r`n*6+FwRR6q%kbBAJDg5XWuc_WX zPvN46IMi%Y{r1jN_}`JT%LpbJy02f8r{2#~XkX8XuJ`j4euno`&QsV+5TsY0y4omI zq@I4zs|)o!PvJB`LAlR=p28ltdx>ECx6hSoY$BxdZ}&V;;ek^~`J33Ecs04q& z75tU?w?Dqk+g97ZJ=58$L)p5s{_Vxd=P8^fVIe*J+uJ=)VVmp?KxoVEJx`(4fc5yH zQ|twB*g04S$i9GF$KlldPhrB<)Vb66qdT=x1C8IQ^AtY# z0pX?bN7ur~!$^!Y{^+mbJcYpbJR-)pqJ^a$d$9ILyXPr$|}povq!cwh7nckA5B7*BwjMli)8|yruY~SHF&Bp`531**W&Ia1eq- zQqEHtBwXFAKYHEU)ak!ge{|v+LEol>#~=OTm88Q4?T>zJrgwSl`lE#o;*Y-gY(s~h z{^kwSFtatc*H=n0)=AtkEJcU0$&*npE+U4^UeuoV#N#`jX zHxjhBebr|CeD(fmcYk%LqvwA1FnsKv>pX=Gb?N=ny`HD=d%l2C@=fqh@4oXCrdOj+ zzf}J;H#B`Q|McfPPhsOFXoAN-{o`T6rjDmqk7{TB;7q&==P9(E>+J7O$A9*D3KJ0f z1Ut5Up2EL=t5u$q^AwInsbr3Fur}jM{8PKfKmBv#=P#>7U;G(~&&TYA5{D`?c75xj0>SeLwQqGm~a0kAHd; z29YyE?O8+m^*rzYfkx0z{L{-%(||ntkq=mI7ODPuU(5%O)SSEV+QJ>o(+Kl?T_9K_3`lwU)BR>^`u7T?{ zT<_xAjLQPj199z(%cFnT{^>WKGTgjd{nJ0XB8jCv{^|3kdqhGBC9ES7T>td!N5RtK zpZ-_50NQQ-X&u<#r4EBz-s7MCM(#&m@Gr58&&H2FPkop6BL@NIEL^3yj>a_|*HyT7 z-XHt(i=_)~e{2jrn${od?nj=TE9O71KekGM7=LUvK&1F%>;BxkKlUuiOSd2S1j*^$ zA1jgey`69WeTk;AZG5sH`2kt>Zq_Py^zu+TD+vLE@bKR~dEKX&01BUpC3KQ>aGB>O!6 z*o!VCiY7#4QWA=;KUPo_f9!|fvr)ADv5;Qd+mAe^Q~a^H_>m=j?tk|qV?Iyz$9|*s zBj593iS>ugCDuo{X5juw{LaSpH(c-GdJR_=dUH4UW53XT`Tcy+{xpys???XhOwcQNKXTK2h zKk`x4UVFanug%55yskYzoxir{e&ntrJpN51}aS>Jr& z{m9=An(*aa+mAf@5i^~M|JUA+{Lmk~1MeHNANd%p@KXH01Jn9{kqQP+ zf6wjJ|NE8gM=lxRkz2+I?ATjV_apCl0lI#N{@)MIPbuZXE295*`}>hkI49+8uYXzm zzYm>}Qo@DLMU#s5nh(*|%YNjuyzdCSwEo{r6zl2#-H;UXqW!;!HQ43-$l2OmX|I&M z{@)7EGW1FCmn;@j{J-(_SSf4&?*w}pn$G_#T;03>H=`6({d)bsXA1f@9lZYEa?)Xg z@&8tOEe5XtSLmSqzvB%Z()fR^QY!;ZJr>uV=9l-p4#Abi|GOLZBd>TMc|Y=sQ`w%~ zvmbe{#cb>@>_>j)H{`2t@P6dEyJzJYk|F=09L1?`Kw;P1Wg^X*4IFG{_|@%Ijr#~%BU z&p>iAMrBTqey-jY|#3?A90@BuE!Z5}8D zq1J^tXbzJ<`mFE`Ory$}aFbQdpt(1*#4 zAC|&L?%&4PT8m*;~U8G_FhIddDPR%E=t3dVK_Dc5Kb- zzbAdfGt{sh(E(6>=EDF>*y`q^?a8fg`ztu*SohGfzNOZSxZcIJ6_>|<$o-*gkT6e1 zU4bx;FiX!}?(;!#XB-**2=U_jea&D4@xE%f5fj??K?T>H!~^H(AmpbaGO?L_iu+ z>{@dQWGwPtSX>U5i1l?$7+qSF@k0~ww_FxK)DI5{eHOF6}&PyH@HlA0)<=t&@{ z9*Php4uI-M{spjvt;QW`lN6tX0)V0Vptgx4%EgNvxt&-#5}K@w({&PR9&m|y;(lzM z**o9b(k2ft*mD9mq8@-w*7E|VElMR)&61CjXCBq!3LgMX=69UWk%6y5u|azG;-PXZ z)F+%5>^dy{X>KEwgr86rC)13YIu|3)TRAVj51EAXX5Wo_) zdU~YIcjHNGlwCl)jDVHz1U4}NAGd;-g_ORDa@D8}P!L2Ado>fyfrek4`A%qT<~z|u z$tzx(ptzFT5C@4oD7>IW~ipXC;aFSUdzKUz|pq)wAA5t?#BTB z2>^dQZn*$`6C{LhV?BOspz7E4hHhI>5Gvno_H!4&ZUNT(>{%DT+%XTYp$y7lj@MY; zN=P``YIbfv(vnBWh`Pto1#Kl?Qa9PDo0y8}A9`vn_ne&uB&Y|eUqG|tOde-zR8&8W zixXs<{c;;$o*!t7VOttLPBt!(%WQr+Lu%Zhvp1X%$>@IRD2d&9g=N7cJ!{j#1i_ooo}=-ZpLF>FXtP5T2N~FfMfx#gK-^!Ydo%#ah;AUNgp%k zn_v1`JTXmozEQs;#dX7Jq79N5^3ZHc$7aQpBPeCD$E9Tf zDn!9A`+TFnmnIS3bH362$FVskcwa}0!+^No%^G@0<3pMK0?co5-Hxjf*JHSz!nO19w3EjQOWX0ZzX0F31`vL_UAi6iC@44j z`#xhgiuR7VHjD#BdtZ@_;&V`hF>i1q_V(gw=N(9a(ReO?Wa;_e^Nsppx=N0xU6%ZP zpRf0Pqxk;lumei10D5dO?g!#`HJXq|VABC^_OgTj6ogw)7KXATLt}PWsq5JRoMl>~;&-iRbU>Z#at0v`ij)H+f zJ~aUa4;(OYM5v2j@WIzuM10E^d=l~np9H?(gG0LU1)sqKIc+0Yt)pquKpfzXFY(|L z6|l-+DIbrN7Y(ZzGpwp3T(zkNZh*LY(fcVK`Nlm;>QCuxs=xCYWop+k$Tum0F)+eC~_ib8rpBH3rvBxK6=UhpQA< zHLfVGuP{D#`{x_Iw^bA}QEk$lZ?r^$+o<=@T=jP<{WwABQ5=r#hKg?Qe4|#_7`T?u z=NoO2C%A{=28$FKqQ_eTKW;$b&?7dH5?oPF* zU}x)UJ81i&v!Wyj05Z1lEuXX9lTC!cRL3)X#@HHCq^@v_@J-{=516w=1aJ_gUB z*#1Y+^MFMM*7k#iPk9oO$1E=ET^IK~Jqbk*V7i+LPbH34@@7U@$$HXsS!DgMm ze2b|vQlMyjW6n1^{VnsIvpP6>@r|MJY7Ew3Jvi@#&w0){_dMsE z&*yy3=kq?FLn;iQ4&Lz$iE(GGr>Bfm7~JqfG?|#^?R0`p*gS7%Elh$YzV%sD(8RZX z!B3Sie)G9`>%k)40gI?XhY1M1$GHvnRfw;|0Tj!#wO#BRKD2+ME4tFMV2kK@-juNg z1#QmJ5`|I&wQrJtqeHm70QlC2^zx{Ye9qfB5dMuuM=LBw8UBjDq68YRrhlVrPlyTw z-+GpBDubRdqocgw{*CVMdCyClPgyR-@4~SMN{>48fmJe-SBQ${Mf>f-|I81Tp8c$ z=^&Sd0r0Iod$F;_?!28hx|2-*x8hrqh1pZKgMx4U{RC=o5zm+XR8bfjfjZq+btGrLiagny&=FGX!f0Tu_g!8^b% z{h{IS_it1c+P_iM92zj*_?7bfot5(Zot5VKJN4ZI<6Yl)40Qgg6ARwlxE5=uoq3A! zY9CMrbi~1cceVF#v<;l$shE*N9KGLlJt)wH~ zi`a|=PprFa5M|IKV%#MI=~0xD6NlNoq`wjYldQX>J4Il|FY9II6hDxL2rZR%A(iyy zcU1N;50{zkDWj55Bg%$IDh8315Oo`hizfUV@$F5JuH7Yl5UaoY8Q?zs6Qb!8_?;N0 zuYJeE)Ig33sy5~i5?A&C?>aC%yle5b7QAaueuQp?Rybr`)^f_Sc534gZ5>fYtu6IE z`0=hcE>Wf6g9`6Dr#B`y9q;XR?Z_X?WKew};Um^WWW%{b7f9JtNg_+#iyx^hXUk z$LtRi@0#=}`h)SVPqf~z{b7%HZOMv0(H{o|-gR4NOOrChfEVQ2vZJX0f<6?ys~<15#k-Q@m`LDV#|SH=g|&)tmyx89@(CD(=D0KQuIrz}xMRHQ zr!C~T`xo!J6jP54-nE?YuGbAS@UG>AcO5RDn~irZC%o%GSdD zcYRzu?N7XGCk5}C=gCUQa|cAcigq;-udcniqN|yR*9(*VCnU&LK)iOvLBPg@6n6v| z12YUdYRW{s=I;PwV8rXPMp9iS8JIUK;?-OqLEHE?P7`P<-u3cjLUj#Ye^}>vR>N

=8cNrAeUDZPgm+Duf`($e>x>3&D3{_dRl&RdP5x4c?k~*i z&Z8{NreI#*YfsIlV_xT@4b5gVF|XWgjCs9muhDG5F|YTgvv%}v^Oriq7xU`tFZI`f z>5h7YHmK+k2*)GzLO2Uy2!gWylm1fo58icnlBI7HylamHh4vFVP~Z6DU909{NHgAb zm%bc8%g#1Kp|M<=LK)B9yR^JHHZ6 zgWRNWufuuZ*wc$WoeAU4140rwn^k8s&gKPN1io{h{G}G77&pQ#2%`~ZB0P!EbbM#Q zq1=TM-}x4LG$6jy^p~1h&NH}*?>vDE(ea&qQG^e^(|MIWzOyU83xw~C=QsBF&Y=EM zJ4>XHiSPWFA)gX6;EV4(!2VJ@F!@VN1LHeSw$!gV_|AWrzto1qER03LcW!P+qf%Go zlpg}dVh9x`zSHpx7z^V&NAK1dOT_V=ms_i-;5$#@D(d*oL`xM-d?#0t@tte_kX4lU z&Jg}mN1e;~&i=UYQtMxTscpcnt@zG^%3tcn!Rd}~Gt(U>pvNA@{m;060pTx%BN5jI zp*KPV@SPU>rFWfkCsg6yc%FSK0h(Z>XQivS(m;AvVg?$K#WPTMTmZDt7PW9VN}W4* z+=W)9=dD590I!(Jq)0S6#d~;dbm)3 zIDsDW^oJyRn4mwjqlY=-0cN?K*q=yHo0-v~ItG7aoyWiaQvcEZQb#W&ks%R=G64z= z>MynQ$_V&N-T5m2A_P#_7o_j`E|uFG=k0h+7P#{7p+FeG<qHdcHQEveyGdAE zaDS=G02gFn9~BbXU+M=fFn3%1rCxFx8Bu|B@bQ;AkPo2_?JqS6`EC5A?(GvrC=3AH z@bwh~@kBEQ?IVs6Fc4lJxV*I9(A`hy?gzA|{~!zqDK(K-EpZ@+**H=c9 zH4>9Hu!&d@`Qbl({H5lv)LRrket__w@bP1QD>{@U3~iwW>-r+a!oE5_wUKsbW8L34 zi2yACE2Uy-gGCK{BEn-D6nOPC`2eqn)gN}Zx6RQWL<ZTjG~Q zXKQ03xFpb)LN8Bs~jIZ=>hYXny^LTTSA@U zizkH_9`gNy@qAb{y3}x+CBQiNZ|Gk{s-J)INoBrIp;AKlOWp31TP>gQqzf>ES!!XH z&$TSGeUIU2gD1UI&7;$Es{efP$ySwzuBH)=4;u50u4ZRPJuf3xJLfSXRmk zp7f=98dCZ)v<%~mh8p0CP`{ga(t(?>Qf549KTR$}4@KoL)3v6W)38g+(Y|TP#tb_= zY0Plem}1aR%SbGZ+Od`=4#Jn_c`_37+)+Cg88L{!^HXAK@uVj{0wAh8%AFGX7*E=JyHrI2^NA_CyHFLbgWxP^8#1-wPh5H0=Sny4~>{wU^j3{lFgjp2+x1{SlrGF&P6rNgn$q z!J|}NMLG-+q&2NR13xIG@+#iV4Ie4^fHjH3U=*w;Aig#;8&X`>LF_MeZfJk0S5GHF z0IOt)A1#;o(Q*?%x;#2Cel!u81L8+LlmVoFFyKe+{iQY)KkD2C`q`iO(Lv-5xOwm|169@S_b_jgg4sgC8A? zRMrs{7(dGOMZL}CjkKr09#o6%HSmu_e70WlS#mr{(-dqJELLT zZhX{TcOq>+G>>-HAHA)fQCJCha> zp7x&TX<4zQ`tO);W5t><&Y`qdy{kCRQPfhbiP5N*%AMp>xdcyi3nwJL1W~yJQMnzo zKBR#p^Tu?`#7Yx8sA~J=#@z<5RJCZl>Qcwt5pakTS5g^ zK#h&?$d}92Ms`%222Fzg{RNHrBTf8$jt(@>hI_zK&(MfrWkM3FS)wq{c4sE=jfFdsU0(i~;{n3c$=Dj>L!!F;rQ=&Y zrSNoWcnGF@G=Xa=-9-E28Z3_P^dB^S&sVXm=DNDI9D z@bMWNKV=4*r#Jgq_R1#niYCL3d-B;pO-A?z*<=Rv0Zmq3XK6A8J5g3cO{QZf#{RB0 znNfgfGR96ES7|g^aO}kTYj`E_xA_Y@tzI^zjlZyNs9;|NC&Dmi=%%>aCSu_p!`U~4Q7v0YIi95gI{xPsq`--2C z{=)L0-4hH+Zx4MvqxcJJ!8Hx!FYL>0x`M0;{=#KLPh$EDi+z|?#Uy@9e_@|h zQz1H@L_=Ts;7NA%x5txw$?pQ;N#5o+_IMJsw(Czje_`KY$O>g1`8yTSEMN$$mk z77)5e@%*A=#1jk}XcKof>9H%)(^v{=i|ME$BMmYg;Vwoaj++gh#<1O>cTo@dloRFJ zb869X;?cD_8rg7;1|BO0roq7P*Z~SxfAsXClVlY#qFi--%sNCPlTinF7;;o!$y1_m zX+Em(9Odcy!oJGW&4s*3%MdAx3X_$0;|o<+=$91f-{p@dIjH=Fr4+!=DSE32;m7NN z`^2>lap&QB9m1suE`$i+NyuItroXU>H}kwR6c<_$dRhkmMY)MyUIiZoUy z(ZgZ-0~WY7+Ueo}D3V4UMe={V4yny^9k&jA(j*vuGNW9wQL(!KmY;uYn!e06~9Lot9|qr z_RGCob0JDkA3i4C(F0)!f(PL&gi#2uA>4`ZEW#}avk_Jx96)?XaDQRtaAv`_dtNEe z1Q+i837k|wXF%3~TCL&;)s>3jFO1Qv^0-x4hA~;xVvYrC$pbG&0eg^{oD%*hka&^#?4ngRLLj_|zrV2A%M`mSTFMVE;^QwYX@S{22L>;4_dDvhO1#J_ zuUv$;hIH^EcX;@CktJ4tVQ0_RKMHLZw!g4njLk}(8PB<&reOkcf89=^w9podVEbX_ZAjLfeJG59ovLb10UZce_>x&Qh5RJ z9i!l6hmcLQ>hQsL90-45r!7%fjIMg-A#LcJ3lh)>iodW=m!s?b%w?v&L*P3W_@*+; zOQG_D`wMHtB;oTLW`4$Z+_=~$h4~)bx?an&eb0-JR8o{99o93n41t>lS2hW97>Dj?34{ zW#OS%uKD0Q8osAdXnP*+w(+dh#i0M&@Eu-ZG?c1R1>dpeOKOKo;VorWqYNY|j&dIY zmg2aSY94Eh8NEH|prtri5n5qUon9S-|5wMa%xaXn+%w&|WS(z$)(%3*8l&+r=sX2m$M#-oLcpR>uoyG{vBirOltg z3}NC0AoE)ChKCo}RF#cNn}~r-_L?IR12Bq~!6h6+1W22Pisi(%AfN$m-8rI~Cd@)b zGNd3cfC>N&I1?)P=v+F+FTvBEvnRL{XsiP?p!`XCoEs*7U;{h6+)wy{3*fEQhoJQS z`up$$mrta1P5AhMZc6%pB7UIXcrm0gQo_Oy++f8I?7RPkmxQTKN)QTu;I2)I1aa-B zU`_$>1MBYue`5SV`xS!4DgGA}{J`Jje<68)VF+&9VqxeChTz%)yXm z{J?*gaX}Ho4@mzD=UDLry8Ll)`Ck}V!gh-^Tq59qVeeGz=S5M!;rau@;kfUJ&~$tG zPaC)krMoS53v7*DVF-Nz5HZL{hDJh|A+ZsxbqVWW5HZ0?d2D}Poq+| zm!E;r#p|_La_VIIU#NN%jD_vxKP=W6OT_Kv|J!7#qGB&!^d41F-}v&-2Wk~fdpTE; z?d2Ip6{WpAg#U$Y)7W0V92Zu({Of-K#@K_||3bDKI6w5(vj|7v{zhEW5dIHg7J?h$ zb%Y4m%Psn#aQ!b--p4c0d|YT#`a$l0Va-m`bV?}Xzy25g(f${lHtLJP3UBiJA-5EB_P_URb@MKTlYoBxGrq9EvF z__TtTr-IQ#X@-4zGd#e-AWTJg7hxR269`^}r3l|5yo~S(!fu2EXkRBh4Yb7m{uf5< zCaZ!p6Jn<++6Vp@*jJS_6Mjgsbd*FI^gK1Rr&ydeAx?xp^G=rjL?NO5FPygq?Pc}9 zuw^G1*I;V%@xQQ&Pm2!ie_=NA+xTB7#;a!fU+DapYHyMD^f?w#K_Gj&zyF0ySYM^e zB^>_?8mnAzR24elz}VAUJ*s}Iw5Kn$UMgow21pP0( z|2D60n(cq#jwKQCzp&O~pEvw3aI7S}gU0{D-B{sS?en8<4`iRe53y_=>D7Cc+qvBB zTve8}oOHk1MKGuDqyL2*X!1<|3p>Z@OoRO|e1-~|_W9PR2269XXoP#7*9o!V`Clko zL4zlNeSXlp!k*ql{|jevc>(P6@95=0N$zW(KVbeBra!FkE!{}Z`X$n*2>ZP0f1$+# z=z1UHk<>?VdRnw-Ut?d9C6!rT3cU~Rf8pf&d~)mhE-s&K>5otINnw`Hzh7+o9_vXP z{|o1;d360+0RIcWyHy@4?ek+aKl}V6I4uH)*_VJK9KGSirNUVQ%Q*WTfRhr`KdZ)# z(^9c99$T!)hAy{Q8SWFX#pWf^)1#uwVv&pyB9Lln#Q`L~{vE9C(8 z`77TEYM-Av`){|;4_#wv2gN?$c^S2XZl7T5%bOTr2XU1)10Ik<`d{e3I7agFW8f|H3Mu;?48BT*XO_!nlf(dtv)xR@7G9GdJQ`cS$MUxmM7BVoP=7 zO|}Ha@5mpI2(YCUD^+sTlRL5TT6+*;le=U*@&hqbMptbtc|gcbCeJWN8TrW*P%;&- zb$VKq1$)=&0QI|y6CH&eT*V2FB2;xMRRn+4s4Cr4wLN_2F1ZWOt`+p3sydJgoO=tZ z=g5ChscHvnRYh{HszB2$#i6MmpsJ( zXY>C#_)lBi%jgwtN}ow@D@y1seF~rnt}2|c5$D?KaF<+!Sa;balyoNDx0^}#Mce?? zR}=9>xu^l?o*G~p-<6h#UrK>RJ{c=D+9)4~``BS+T&wJ|vVq8;rLV+MXk}&d=zdq7 z!=c|E{U?N{lDUZGw(jgHqkDJRSp3(M+>;oE#-@lJbMU(;+Vvea>%_UL9PXJzDRoIU z{(H*kzFisJ$4_;kg4Bma-CQfEL`Pxgijpz7p+CLgo?I|R?l>C-S7&)~Zt95wMM=xVyH&MNQS&6r&RFvdfi~II4swYM6p#9!EKEXe(EN}>-vV-u>U6P6a zo-(>`S4Q`RgSn#7)o1BHQ`~+TweJmUK-dZEVxk<_TqkQ*gndN`Eu4w#1~xjX$pu4; zGOF`BBpS`dbgU>Dg$U&{2XnnBvihp(fo4fv&5|lgM&dP$tFmbh<2)2u-Oc(lo|)W1 zGe_W^-i|+Zpbw`AO#Zz;)LIo{__A=u{CKi=ztO)i=;_983;n<5PycTiL=}+!pD>7O z@cy8GYgO+;V>yZh{V(#T|JRMG2BiPTjjGQ1$I$=PUzzm(SwfVg|2?=3LI3654EkRX zHvQin2K`^j1vC9$MD(9+&_-eV-m5%JSnwK>=Z+bovH<2*{hWbVKpdCIEFc;s?x-Rb z06$Axu_rLj^_>GJQKIABGnoaHFbiOIPLG?Nm2LS?_r7nKge?r&2I4H2B&d0<_10S zWABNIaB>{6qH}D8A++T5CPUbDv(6BV^%2?Agufviw~2!`c^Mz$9zqcDbpzvQFD5vM z+=gNZcxrwf#B~_k{9|ww3*B^ZN4rs)Tp6nAQLJ?_sIC{~&&rJYFLHj}KZ3I!zA7LS zfXCf6A*nSxTtWBpN~(_dHSjb5HoA%dP&hIFlGjZ+;A)6J(z8(8C4zQ!&q4~Ap=ts6 zfOIaj_Eq8l63k!}kUw_=ilwr(TOQ$p6flGQo~2}{Qt^}P3j^XOKVAlgZT(=iy*vm1 z`J7iU97w8@532Jy`#+yf*hY4ub8#-|tgYvBUZcmU=X2hq$LW5QIPV=I4q700Zl!P@ z$bM3M7V+dvNiO2)3{5G5u2+WM{jXbw9v1QGv{;8<&e1Q^(9>hbbI$z$ z?ab$M-ZxXWbMw#VT$0nH>F0Cq%HsjcO=a==r1vNGPuA1mUOEE9E2;=6*?R4_#bNYE z@`d}cKkUxuoVC!dKW=5uG})c!Ef=bZaK`h(BsYqvP)+w@E+^TyN4yjb=wB#~HLA zU6f#qVh6vA*8PxCS@dTe@0kCiir_ue@E#HF`JBX4%=079#@*BN6jCmEP91mV`JCCaG4A+$ z&fe4Ixa&_}i7uT^)$KQ99{%5n)qlOGlp@?&8kWBh#HP>-VGr`;YHm)a8!5z4QOAoh z--%Ht&Z8D{pC7$h-1PByTT1k(%5VGnj5VUAJl|)KhWZ}+0WXG0016_A*f^i_i?5mc zz`05FXtD`eDPBFO^z9KrKBmsro| zTy_&voIIbCK3F-QbB=r);(SgjR6AML_D{H-!1ji1D;Dt7B9JO7f8Ik8Se6~f&g((OeZ zhE~K*6ZhS}79`1 zh`;xGQ5eJmQZCbGiXJ%4rA|BlC{9$G4wpD}S~kO%$@fHr{YwrPHcPpsM%f$E;|Xdq zeQ!tthML)A=H3u)GTs}q(rq-^Vzi3=-jKA#SUlpBRv?w`GpJ6h0o$er_zbGkdP7A? z4+H4oVK8udfX|>htqnvYdVtTMIxSg$;0BtcKfq^DopueB1V{$X)Cl(s>_#$m$K_a0 z)61EBI3G2ojekkc8}QqL@GQb>2yY{7K==~jN4nSlRQVJXvwzO#ET3l?(uzu@Y>qBlb zLb+e29op7ZfaKOfSRuEft{tX-$rsLMiH6jz(!XR87ozW%DMerT?3bDO6TJF^hxDOt zgZJ*7xZB#Vb2d2etJ(y97ihoCRs6<&zs$;D{v|sw(vehorhiEW1lsMFIl%rUqb=vD z@_w0)mijekzYMp?KgYl1`A_=NyWB66I*Uf7uGnf#9ul0qbcC2??w48m5a^xv%PgLv z(|g4C%e<^x@pSdNvR`KM!&F6`C5@V`R?*xq!&T({G98R6%Kb7S{7WXTi1e!wL*XnY0M4ZcA#4^fU-J*lAOJF{W$y-y|m>*;BUB)~iSRu_1oq1`!M|kXYOzZO7lOtg9G?mi7 zcm?uK{mt1<8**ynlKg^GpsNX90 z!>j`6)$H)5?uS`o^)LDTrTRzt?1%XalPek){UTZhz>8YwSRlXj8m8UHPQ(K2huJs( zlEd|4p#w8LM+t?2zTWotFL@XNV2zDqhJVSe6f5_y95ntV*JV(D5~&`6rX-iI^RNc< z_b>SoV$tjY{7Vjk)!*E|(k%ayGn~?1K^5rDPuTRv)j1qLZ0=tf%uh|(zcQNr!-w`S z`QbE@xwnY%r23bfDwG=d_$K+6Eavh8>|cp_kd-7XSpE(EB|p1XVKJ&z$k1Q-`j^}Z zlbVn2m?*$Z&+P6)-&E%N6f|lG|B@Yt`u&EPpZBknW%{Hr-}CR^X#1We?126y|D)#N z@&fvod<_$VPP*{YDEF^y_*&(8FGu10&@X>);n?T>D-Q{CpH$&0`&SA|m1SWT#upD( zpYubj)??+$`&a(DO|D!6>|c3e2Afyx&JP{*0c&+J=>InVlK0+kS-~s&SFX8-+M!bT zmvp+-<*~Vch1-Gmuk5^4ZwLSVD_6e{zupMXBe?V{-BWlFL01j)MIRp)e**jJUove5 zfGDq!z(AXbdqFLMqgL_gKvlCeKEYa}S5B>8MxXepQ}L$4Sw#svS=;hF?cu5W7r1D0 zt%|1oFWAV8(`0dK<}cX=t;&EfD$A`JrVY~Q^CRJ3@(!G=Y4I=l-Z^M{34PSt=Ya2L z85r8XsR5eLJ57CZlv5ygYW59fUV>3!7%xmb=;z5DPbVI+MRo5?T zTm00+F+GvNkF;3{1YO2Gct$NoFZAyMMAc&4NGQ-7Q)dp{1m>^fLC@(%!nhR=I!upK z@t{}gakS2nc?(2bB=De5f|w?nZbN!H{oUUIQN^Ffjrj!{8);RJA`o#^nu!Kb*WE4E*7}U3nR#;6bqiDmWgr ze4p{4M+&o|Bypvkf1X6`tgFp8qS4KEu7^HUn8`}lp`95Idgl$YotuvbC3hNd1n#U` zT?LmW^<@u55vUI4^m=VTEau4Lt2-JmJr6~Vp_keZ{dvH0Q>FOHw}Jbk)BG^{qrS_2 z><>FU=sm*P7@$9{xKrtmfp@9>Vd6pS=xlbzgZ^^;e(eu?JZLVf@TmXX=?4WKv`-1Q zgltj;58Ad^nZJSaI@JlOG|<-lf!iw7m1V&XyR zDNH=*hE%2(i3g?MOf7;bhBM5Y@x%HFRFlB3L*V3val6cT_L@oUApnkm6 z77tpE1Jojc2VE|#baLD&c+dy#P)NCGqB`zOJm|t17-KoM3M#aIf8i5aw{J6{oYJ* z5)Vortl&ZC%eNu$pj4=KvaIc&@#TyMmCpwd5Be7-H4_i|vv}H{c+gG?9u&^zvB5AP zB2=`ii3oM=BO>&fJN+jlfe4*&yD}k-7!Sr^Kov|x=z5$$AP}K#uaS%)5F(V~e`#mZ3;0$uycYon`6k8ff!GmTOQA6n(q2A+281l!1*4=@IVm#>9k)j~Q zU$}w?{Zy=#0^vdPJkfb>^Z|oIU2CveUPpwAW7Beag4XLpVnW$X9H5JjCXpVePRE1} z-Cvl{vnN`bO~Hg7h0X5?b_v^LJSKM!|y?->T65Nb*u(s8rTN zY!d6Of%jubGamHNE4iSE;X$Rp@FV6}@Sr-r@!;|oK6b0XKjI?rk5PwXb=Xs!A+;+J z_niw!-qUu_{SgHzbpJKow=E!xp|%P4VyOtMO%D|FAB0W_ha)%EG4YQdTh46s zJzx6(`wQ>DQ8{0m_K^lY zUz--;=K0$6WS*~0Pv-gB^kkl|O;6_e+Vm9Ud~NzJ1^;L{D4Z5u2NwVM1MrXNtn+R*;O^O0XVbAkrsk34rAgi##D-e1eYt7iHO|Gkrn zpON^;ITny;Abh01zwo313U~=KvL8NDEL$+8#|-mCWot`Q^cF=293Xt;aq729eB?q4 z7PP7ONFRUU-*?nM$_F1A)L-~bb7%wvz(?+aB@OfkR3&NRu_+7dA+Qt?*GDm+>G%$; zhv_^@@}Kc2wDqw18_qatfyBhw^T4hE;<_qInxA8fPeWJ5uZ+eio82&)gxiehY;DM8 zjD$lp&@KS`!46%Il-OxYr7S}!q-&D6Oa1pvyyY>ixt7}N7QCh5FPtH%lJE{1f8iHn zg=fWE_BlEb-ttPsqAdd8EvMp*iMLz?=~PI^)GtsGz^eZaoRqn<*3(l)Dmn;_8^1EA zC%i6kGxygzC98PLwb1J^(_p;iv#6knxBP;inu537^)d}K9dDV59WcUKKVf!VcceOs zx`^6pS6oelCjj0u@p>K=NFNVscGX>12-lIg&*|yfGq|X)SiS!W5mfNWE_g|Pp$_5l z0^ltl(#xYIgb&{GfcXm_d8Wd*beb~svA+Jo*B*v0wfZ_U^iiaLp^3L%d)zmbSzZdg z5AHAg*Lc6*F!M9s@(OH8ved$S&%b|`?R#{vjlb|VY91~xAl`Bc+?V*{EysN0hqt`` zy$IkfQ?IiuLlwN`o-37Q=+`4L+tOmu2XEPT4OYsGxAY9*f&dW>fVb?K&&CWpyyY9U ztTDx)|J(4E$-=BC?UM@L@^|>IGqmfUU8OF^O}r(y1LG}S=j!d?kGI^kGu^Qj;YfV$ zPW?*v6j~rK&{F@WkBW7Kz!x@Mjbr(N;`kyLLW}9 zJ`&NhWN$U?f**WFBd)$;3L(enj~FAnx#9Jh{2DAA8Y^L|GxwG`yLwCiTL^izKipaVY)5iVp*P?TtYq`@bTGZOZa`0 z`aL1a`)yPc%L~{)|D!JX8~exeH~&6>Su8s0gG+7yfbDg;efkjnHJRLWMzH@k3Cw>u z_laMj5Usgi#37*^}4A{i%y!e$_I52V(Mry3qWipMdL|5O&qUh@A z>h~21NVE^(5fgE6Lab+ldo)%ng5-0w|9(P?GDxcML3itBx=&Q{8uA+)m3d-atDzQ- zb+_dQPkO!LKTUrRe6IN(-bg43|Ng$_&#`TfPO?4VW(Pj;(H4JQMVu(nb*5;Gj{<#9 zj$M1a^10a_-)*sN5BvHA?w@jUL>jDrn(%$?u$?B<_qn{f{2~2^wx=G(B(EKNJbY&N zpw$;9bkkX7o$w{d&MIs1mYr4B(hvmH8YhCdieZX5kpYC#S>@MYiqhrstPvJrl+89Q zH)uCrL_&*~HobVY?2A!#!%dA*K>o;`5JnlC*f2l}qi*_bEXZ|-w!=AJnmZTUZ0qto znLYE|Sq%ja?Z&UDlVV6Nf|N9cW*>&#*6FZYmSD7OOzjQe>)Sv&Rp1hJ+Tu$1-A}8= zA%k^_2h2Lpy$OWJ&CyN}<PbgeQqsN1o4XM#qE>qYuJI5tjW*FY z?ua$=j^MncXlgH${`n0htw&zHBAHbjF)gdUG^=sP2Gm~sZi;`Mi?>qJzsx#s_>Lo{ z<^Dx=o{qfYh$KypGTu0ZZA0!XI=r1m8HwX^l(j>L%29U8WtLHfw1ae&PU~TcsQ=T2 zG|HgW;U$kzK>l5|D3(S2*=Na7HWsyjEpX%}j>t+kwiP!6u*s@S3{Mo=4RE(C=2a*Q3|-xR|&N4SW~A ziAuNtB?v?PC0wySj>2Oo{tS5gTo#Q)H@xrgB*d4;v~|_>Dg-LFR!hb!-U{#aw0Hdk z3#8YL@r;M1y^uc74Fm&f-iQ6r)w;8VY7X9~Iy9y`&PRxLWH_ejSGuRL4$pE;6@cCz zxwP5zHom2#w^4lhEa@T*ddmUxx6s?dFF3-F-qMVdYYlqag~`G~Z-c-<0@0fnE)9il z$)GnkleI!`TbOw3{pf8W=e5-N5T;dy-bQ>&zx!7t=xz1IcJwyue1+cb$PPtsX=jF@ zx4|EVLvM?IYbw3HiX36n+tWxKgx;=2!&>R>7Lg$cy)|z2qc<9dmvw!79;0Z=0ET{pYudoYykH9mTY&&|5xFwEpxq(7(=)Gg&M2=4IlI z2)*T8Xh&~d&Qs{EZB{6HTY7p3di&zNaOf>v9*tWV?))|YIl`v5Q;|3bz3oK9TInrH zWC%iUH&^-5+X#@LL2oy+KRFVVtn@Y(k?a4UhOY3nilY0S{XkIM=!vIps0-CLzv74%RCuH5^ z)iDrRwcEN8$c|)|gvmG{1ySS3jm=$@7^1PWw%-(vjDd#lruKAP`0u@${H;Cm)A$V z(Am7sVaYYn`skZeC1qo0gStK%-TOUv))seGCG~Yi8oN=)Iw=S1q}&FNvl5-PB}bct zc^2l>Ca;$6`51J4c6GYlYH2&95S}3**lxCpx6lc!cenRAH@MR=@@OPjkCf#8$bmO> z(s1bA_5vUkVnFb@7w=)GLJM^4(PoP0kb*pJ!(S1-Tz93>%c49T{d_-O8gB%}>HTlF zKK>Af@W`)^$7R{}zf-%Iv?xa(sq`ajq&@A-rr3 z_O{EaDQpE+6jdEV3~5?!V`(mLWpdSBTNqDUeq4XvMkyK`l%gSuC3hTl;e-Qx=+9Oc z;cNh_dSe$@{2-}}DA}aiOLAuiZ)6p4$+J7$Q zQK7&3Zx7l2_gMLJF6YzrSJN_kK#>CN)m1{v6p|mqg}6m~wf)K9t$$qw_o{#E>-HC` z{_5Nz&6e-qNtE*a8#wBW@g3%RdWNt5s)~hYfBn^X&TG+M9qy~Y8fBxu>d$#C^8F*e z`YVms#QyTV!@thQLR_@yuf|}#7NPa@Ejaa3aYUl%uLcjGQC2Bj1D%8+$4V0){ngUl zQh&AOBst1%03|5;s}V#PP|9q7P?hh`L2MxXRn(iZ%fglK8<%3-g{!~%9f^a;_bo`h zWzk=)78xMl!{=Z?{nY?;hL8R#87eJ9zCRfy2>sQCXa?5=slPfB`vsPv6?Fa8N}<0x znVPB|IDKE`>+??TK5n`bv6By_8E>tJ7hT4APmv3bWh=K1S#9o zRi95(eesv@Kh(_ibe|+iZ-a0+n-9Hp^3`9Bwb5V2a$XC)J?pE#s%7H!Ur%pXq7N-o zU)&YE-l8uaZ==7O&Ur0506K5RLT~j#p%n@JRn#Cmdi$cELT}5?3Po@ET|&^?xaoSM zu;)-adYiFWc3HUec0Y22O>a|>I0(HxNZKk3z2%4uLFn!NDnEJ~vsIzDx8I;IqJdz9s*V0?1n0HPZ*MYLEBdQg8~s&^f1S_r)nDDq#2XR))r^65 z^mbieh2Dmo8H(QOjt@a^t;@opw@$CgE(@35IwD8d^wt51gV5XYq^+{h+tx*#Aqc&F z3+CrDzb%LCV$5$BpoBp5b_T$rHuGCDUNx28Uc)T&3&PV!WjIbkpsNgdxDQNk0re?Y z91VG$j((1)KBdclEh9~l*Y}>rpDXOmRcC~f*YE2jN7_QGynbyUeaf_)9x!4W+LTTY zgr`mMmEOBPgi#hmoALNx0EFGRQinvL^>W&?NW>zsQX zfb2j+L8^+Cxe2a4tg2{aRYhYIw5l+DKuysA4Q>!MMF{;wG3h5FzCJD&2D||4~_{{X0vPYr8(y{RQyx(Ea{LR1QyIINT?I0yBVo z|0gE6X385$sZ!o}XuO=f40$7pr|K~9AeV4ni@b3H=T-0^gG7WM9weFbTI7v$IjJIV z`T^iR2-E8-cR&ktAL_!c?BmNz~@;vn+I+Ep~ks(6s6M1~;tvXdbV`p6r} z=rBXxi03b&fn>Fpb(v~wFN?z~Q{D(457N0)hT}?v4xKX`kLp*tr|>zRrOXk4-rShx zn@Mk_T_nAw7Rk;t=xv5rKATu3J3NS1NO>*vwwUuO^tM?<_|e;Z&TFB!FMZ|vIuYSV zZ(}*HWj(!@lPdI<%nSR7$oGr-*wNcP-4%K(=oyOMl9EEuTkA{1p|@LZlU)`rz1@r) zVbj|+NF0RTE?nVDZ>NY1LFnyCbcPST-HWxGL2pmqDhHC4-pb)c%*H-F2d|n#Zx3Lm z`3Pak2^o&I2y~U<9NY(?x1%u4Hs-c36?&U5A|j!`N16tSh^`I)xR-*wz$+K$u|1~jvJ5k#v$jk3RT5Bdh8FaGb zC!4e6;57J2I%;mgmyHw=et6E=oY%rnMsreS{+=o#{P@WT&THW(ZceK3lNUsUA3sU) zuk!*HyA|ev}v^0Zh<@&7C~1B8$x!rt*KY7p9hn8u7I!a8}=6;2~BEpZ}7II#TynL3Ju1%R^ zgoua)y-n_FM{mPBDfD*c@uBEViwi+-vwG-_64d^*C{uP>xb*faa)eE9Pa|;qUegy$$rQ^M{;Nncuu3A`uMQ`KV zgrK)BCxt_A=}y^Y;nLdx<6)-w>i93q-peaYVQokO$eR)WH?^ZuXIo0M?43hH&tGK@!d$u%WrLHn!NlN8Z4B2 zZNESB>yFUhM|^+g?#>p5M+O5$y^%?O#pf4dQ7m*i%n%uZ=quj#*T>IS_3@3#lK)!u6|)F$gPjur_GeDC;BCU!$G_GW7yyK){{svF z0$pXu!@cCe0qE^dOt8(Qx1<4*-V*s!EwcJ8IH=ho?`-^-BmCr@Eyu`aGWKU4&a|q~ z+b9O__^&VKa9#_&y~t#($UAjRy#9F7k(}33=N=5}QRr=AJS&izNp zfn=q(E`+xUOmA@(yiNG@*113IUkDw}g8fUs(mjRG@f?KS+?ckTNpGbYlHTSe$<8z8 zx2O+%=xroKArPP+z2$RW%l!5%Ff0~*d@U2NKfQJ5ycT-4vP+)bRN>H7trhkOjmPef^;7xbcKuOyh|(Wp z(K*5U}OY@aTc`=;$+I?EdV@=+}3wa7>Bise4?>i(G$d0pTyA8pvCivp&-<6N=aH`o8O zc~S2#A5G`HmO6hZmiuO%lX^x&VvPmrW&9R#z6mWj)k=dNrLT|ZZxo^_jJSJX$dK;`OJug`C$izx~W)t*rn1^F$jFdRrvS zf&u2Yd!iJ2D`*jl-jaR}L2t9l^+pM9&##nS7B0QLiX36n+tWxKgx=1^CSo6ZzQ_=S z-tGtU^O@hqKz1?aw{QPPU*tc(4aY7M8+z-HS52k22QbTggfJx=Ykvf~%5Vdx{d6*<2j=V{ zR{y>|aK;MsK#~V%?OP$V3jW#^ef(PRwey;~zw8l6cg>vd$6qGr`>8L>$-|iMPvNOj*Fz$g@EMHCey2@rfyXAS=Ool!C z2TrQcTZ~xX`qA4Q&TFB!HbR^>CspWesECLJz2!78nFNrpyZoWh zTid!&^tNYaS(djdABdUbrKnZ(A&r83?F)1 zjs=lHZ}&ed2a=WEh7Yl&xBht59D4g5GfmIS;qMfoK)=#Gh3620(A%4kshUY|ms~CB zZQeZDdB*&f$h_Z-D3 ze5GIMp286bKJ=#IWhXouNxZD*DY3Q)<}X2&f2+}kp!T5q#nkjKKhjir`Fcoe&EzNZ zMoWG&YKk13CO;9=wK;!}6%l^?B#rZ0`3Wag=I@6@gdacgPS#1s)Q>&FNmYI#BK-Kt zLe6WMzgKWlm7j=+Nbr*x!Z;XU{=V)Pg`W(m3CvHbVx+uW_od_~Huj&vsVYCQv;Qo@ z*6613lUI==Y<}`I5(nWY$75aRqaPC)g6PL4K}qVvPe!1B41V(MB>Ey6NIv!-ATDk6 zW65}B@{=&_Ki9zigYfjVu>T;?Rfas=OI||P0P^ymyP8dJiPuYdtG!cpob`}kKQJ7Ud#O5m6Iy;mMJ3q=xv~XowGQpLT_V4L?q~~ zlQ5G8pts#WDfIT0Hx#{Frb`4nl9Q&-JCZD3Kuu zy?u<%@S(T)FftnScJsu*^j2|W>1~F{5QN@3f`j|eTRox-dTSg{U*tc(4afcwoB6FjZ!Kxs z{;~%!%Y1||r2zIH1iH#_4(_(LT&AsGB&07?j?FP?RV?Rt75 zUYYZ8`1<14ZiEbs@bpcPff48`LmuuWj|e3HLi%bZy(JY&dbVY)5ZT;o!-ptv8=UjODVt8wwIM=+OVL2G>WjO;1K2W~{ZDw+9D3_~3uIt~4!1%E)~|F=;d49( zp*J_AuV&I)={QMm+j3;*8S`7Gr9SjFP(=9A+Y6l6LT^q^s?ggg5#dK~V>qv6e!HHN zD)d$=BK+vBmw%nhIH^K!^F>4?=C?)L?C9;DN`>AEz6nKdN$W$<8{z9h)7vRHc(Q5q zb~18=O>dp)Tub}&S1-KLm)?GZRVn!V_A$<7@tNP2<6K#T-mYT1ls~>ra|fiKX3}Ts|4I6MsGIC;gFZL$+@jzW zYD9z|eO|(OE%dpIlPdI?$n%mvJ~5f|TIlmAPO8vnUlHL)pH(OM)%h$j{h2zf5h5ZI z^x1x^9er-!qR{92Uj?Sm@v&0=9RH4_PaFMf1vcWC^l7&~-P%=tez@}Ix5yDTeSU(( zLFn_D`+V1@Pl*gc)~5s3`O#-GNYW?9NLKx8c^ljH=^VT==`%e2>#5`6{{*4) z1o%JEuXIo0M?6c~q-y~Ab3#?K>FuFACB3D>X_1foc{NWZ3ccMWBK+u0>q2=g^j5-2 z6?&T|BK+pV`JC56Z!dCEh2GYS2tRro%XuyG=ZBnBnGd}pA`euLT^u= zAP16_-Uhd_rMK>Q)l_Q|NWf{A_ zz2PH&CM@O%KYAO_c`fvII44!;t&fQCqqqLjlxD8?{=-QXdb>nK_|cogzs^^1Qia|o ziik+i+bLh!(Oc_J6ngvV(@^v_dqoI(+uk}HdW$-~sr1&^xe4_4I}!(>x3%~9(%Wj0 zAqc&FyT*^+makRl?PQb?NdNjpv@N|Y$E&8&TZc&*j`I&wS`EwO$ed=y z>ksFA`uUN0o=lwUo7I35B(H$yW|pl(AjHeF8Z0MBE*=g~5M8UgP_Z*!XzOsSrqfpI zJohGyK?~(*&tjxdE9b`Mxuex%FIe8-{xFW~{d3`7F=~o@&tGoD8|(3^QeLs^pAVr` z*wH=G{j>WsyZ-s`L#2NfqO$_^k9of5m2b-aDYf=b;PX9S?HXS1_~Of3cMsk>tykOh zjv)`)weRC-+Q{SgXKl7?-y1h5?VJ5ksP=6rm+c$Y{)ho-&1>K1;lD8`eji2wG5Sj_ zgI~(qDnEKlPn!iw32;D+NiVuLZ%-4`|DTb*G(hp8=xJ|@{lV{^|HQ7pi{DrJdn7tP z5Ivdx1P@&z`#Vg2x8gM&i`_(iclct=yg~TgVw~n+&+qL0HSQmNHF%R<`yPwK(2e=T z@j>ABHT^Zb@`h~Ru=v%@cZb)yzWl19G;>;6srYWv4_?Yp8vY2UeM>_Fq! zY~S-=m+c!CziOP?y!O5B9<*CX-? z{iwnLqWtR%PmeFh3G{nzF6<$Gx~MQ!yc%D4jCgek6;5Aql6~REd=bC0iQmiV>3dg( z_r08+zL(R7{$5T`-^=OgdsoWuk7T>vsk!jt;ZMbk9O5{| zS=amB>@sJ~sAuSvI}3h;w$UBxqxElWY}9!VT0kpHq~-56#5CXq4ANjpZ9G{C+C_L= z>v3-LWYvsvA40h=z3R%#={w?V*SFLj{a@X;_UPW6{AiEZ^oX=akJBUE9^GHrxAsVG zPJXmUT4dT|1#IvU9UsXH_N_hQnv);xkr|oxczkSx+aqrNzO_gF%gxA-_Q;P+dlWw! z;r6J1sTtp+@MCXt@}oUUBhwxW)<&v5%ACoVqmpvUaubJ@Ipc62o8!r<*N!;@j9knp zN#MjhpSZkfZYaW>buBZY{c=02bgAEyRi(9iSJ#Oa#k$rv?zj^y9&cR};v6LR)k^8L zmRP(e7e{o}xQd|wJTZU79nk8{y(QC8;K-la3R>1uL=;481#5j5A5QwYb7QrEZ_(nT zQn*PwegzgEIPWVXHd`$q-w_8hEtRcpdQKFCT4|^T3ekF2=!)z3sUK5RZe2x2AFi3R zZr#8nO5@3in-&c(zT(!k1}4cmcXk{e$*z#o143Ry$*TCNw~HcO6A~Tq_g*gwi(itF zgodn(Uy{>f7_Qp+aDRepX?hYp&E;Q*4MQ~5g_Oxzch~r&*!U?kP>bI0QImNQ&2qb! zE0*hZ=W4EEjhbxzM6<~rRhsOKHI^nrTG?cWETbmdLQS?st3msjO=c7znvBZUo_N-1 zGT0>?>zs{LeSA)mJ9nF_cw6gnV=-qprj}$rlEDoMwE*C1jn$XZ_tl{9>0u~6^oC}I z9tP0E!x%R7a4J2tX(=8~poe7rfg5O&{?LxzT+@b=;mGGkY>aG)!Bw5Q<8p`*^zw(c zx^G|cqTP<;=miwC0~1M9@-)6YJHxRQ;a!AJ5WYq5BK(Qa3YC{SbbWj$(0Otg{Xfgm zTu7etAH~;E>?~Z_o=^Q#C;O)ku{4C-xwWq1TI!#e`_2AYuk_EXRhIri+H@34L;A+0 z)IT-UKQ&r5I?Iz=uMcUXfc$}nVMtTiTEjD35Dv^1dbhQbK4Ve;0uGNW9ch_UQ_Mq{q{kXcJk+s-DJ~i|?WGlgYs;R4-SN{0k_>~zw z+)fQg>!A#7n06_P5V1rQRn#H|n}Be~%6!DQRwXKgu}v$&4^nq!#!YL_XU5a5YjqSg z=MWqoUNGOCT|%EzMGar2 zeSu!k>k3|C6p%kR2@OwWYb8%x8(x>Tb^fT&4;2Gb@cq;a>(aYpWYkw=By)tbzG7f1 z1YZ0|eMNd2$K}?q%joM6jV=eHTo1dv)SuwO@hdZX5a-RUbN!Tp(+zQwdcwH#@Cort zN~h1sa5SctjmM<`+e7QMrxL+8dKN^{{Y<*=To6t7Zn{6BAcgLW>Ar0N&PA-(Zo$3y z{jzf%St#aGgmi?{5Jn^1jNoY5GODHci*DJXWy=_)u5_!@PpX(7JejfDql{FF>Wvq&^H&fEz7ONl8F0yM-)a6vu~~RDpFG?FvOqYhQw;QT!^=zGe((~k0Nxu z1aTyktQECtY{Zf9)qSYja%=nL#NF0@owI@8UCQqos*~uKFiJAxaJYOFusyoYwI&4|yk5gG3ysz1(%m%}vRn%$tkWrK07n6gQH0YatB-jkWK`%AoX4@vRsZR_u2kWe#OQmN}XYyDEWe%OK4Sly2*^ZP2berXi- zBuB~m9nSSjbriQnt@HtD`7NbCdzs_U_2)T7XCSL5+Eo?n84}~#3JG9~JFC)@yQN)j zWlh{_p6IW~1s`<{F5HZ14pPqf%+*dW_@X{n zue#5y;)6;RJW`jYbdsz>MwF|r zk68!oKrrjj4!NqYL}8u`{3H~cqYBSao~|$Kt32IYc#`r|RG6$hjW0Y@dAg)X|1L-v z^j&3CIrF>5pf>!(^O5->kYT_(QE#*k#x`=5Mt=vnIa{+o}Rjk zl$e|7iCPLNo#p-O(w4MZ`ea?SlV;eh&e~Y)b9EzUC5qi#NYE2 zD(7)(n0M-*<#}fVF2vtGXbOmSJMN+cc>X{a^=_kwS9F0cj~-Uz<4FjFtXQK>71ABa ziZ$Bv`U7Oe8f}^W09mm{`&oa0tXQKtFqEi(BzibZe}Jr5qn$1u;+Nz$Lb`4Zdi_5l zRJ`fGT<3}`(2W+c5NNxXe8MpoBBuAMJRBZe>ih!)jjwPNphIf3&gc&z^c55gq=@z$ zK@g0V0OYF!GXio=g_>1`l3q(EKsKDW~Sl!xJG-=NYh>~C&fsEql$@) zU3KFNvE;x#G0#hij-=VUM!TPL5|F7CCcCKW7@G2?Wi^y${bgjly0C+hF`d%wbx^v! zQ4DR`19AE<%vZ5!sy+A;%*OmBz5Htcg|@YzdM>CwDt?KxKD!`?+XJT`AZO{ILux&_ zUT_e1uGizNK|W7*O1GRo-Dvf)t$;p7`vlZ1=Fb!9Jq}SrN+B0+%fa{M)=XYQg6c3W z4d4scJD68$%=M-g;mX|j)k~mYN-73p3Je}s>8trP1pxN&P6i!k#Vuj?p zZCF7sS$wv(^kV)!lAmj|b{I;O4(qy!XNZE5xFG8I6Y1kHYoI*WnnZlSwruVhA!6rf zH;IzOtUCP*(B=Y!_YvAX1Ny~v8^Wo$Z@~2gTz|tg3D>g_9POg;OOAHtUo_peXcr@5 z@Sb=}yO#9Ws&#C;cG2zHv}@Paq-I5)5UT;=DYPImlIZlF?1o1+XRRkQ4c}6$uLIzt zEoPV}DqA~aJPTwz`s1h0L>aw5$#dt{m!ab!QE7v#X!S)cOQeQP;%Kp2?UbcNYP7ti zwG(ipU>NuXh_W?#;C?7z50bf7_t%cRwh@!DSARN}pENXWHf%_HP$4f`R-<2Xt?rYf zUCMr(6ES;Z1?nhljS8>J=pI#lj-I~_^1n&b)eV~*E!J=aKmV30C>KG!kWhON14Y!C zWVK^a2$ueoOD|>ZH6)(by3>1c?@0k)Z!eO^vGhZ7N13w@zX5scb)7$OBhW&aV!QLt z$VPY`v6zOT3V|%@8Xw~*>Z%>h1FRlD#8XnQY%OVO6q_fr5ZMQjv@oc?k>?=l9=S}z zlr6ev_U&f(U`S$mB#}DCJp?7z#g|7v(rwKqhyiA4QPmx(G+K?txU(_xkqW1xV`}Sz zcv|Eca-jabaYFuct?I?!+6rKCv%`V7;BOtcMD6ewDHb4(@u`g@8r4B?ot(7pJm%pUY{o{X4mPum=AZIS*_L}#aSLA@MB?XIG7zn1&~nvjNa4DJb1gPgiN|=Nsn?F>Sf&)vLe7qADxT73mL4-G^sqK2}{%8P0Js& z6ERu{ZK;!2UxAlcl+|g^T`AQkkcXiS=&w!18mtGs$Fn;AhUwSwFE4%Q0pto8JikqXfrMbdOeGlclbTdpQ9 zpy^MC@e@=AT%BF0AnO_VsSBzB#UJ%NO|$DUZr;I1)u6+K4uTjlW&^}mLYcWdTXX(K z1EV`J=X&iDa7`Y)g*1k!^^3ZQ+G-1)Bbj>(Qeix~b2odOTTsyE9Bq_PY9PIskEyL? zyALkvD++GJbS3&6Kta~$T*2jS6gX*Y$Yj?;tTms`g;;Ao-2}1Ld^*3Vy;#^U6$P#v*aJeCAe69KS0JmHIi7hLwNhseW&Cq`9`(h(shB?aJvaT=kPf+p3J=M@OVFS8C*s6!d<_2R z^BZP<)?=JC&nJcXo`3&X+xKV~tZ_*)M;k!82G?~6-N=q-lrnXChW^5rzh~U3^1Ri8 zG_;|MRG#-TVzoC9ZQ+3OtAw7W3?gklx1NLj4$p}K7!ULAiwGetX!#V?SJ>nW#OTy1!%K1)tp92T8?(7 zux=3}hSKsUh-;*}Y&|X;q=lv7s8?C5i_tqRBe67U$6BsE=?(Kd8HvE}?O0^QAOg=% z@pHW=J@FCn6?c?7Cx(|(Vg*lXcWws_S5!jN=Ww(G9b_W4|I?Lr81u5F9pF?porno5 z_>5<$9V%%BU#Xq&th$0X3J~qUhopRZpWY6bgJ|ODF3^E%v96l@N`_+wLIuJz`jze} zypCW9OSsX;M|ZY-_kP!n)oE4@SP!PJz9rDtlO%XYAIBt2q*7X~M2B0%TRin4b_J3K z@2u2f7c?~Pc!gSo#8R*c*vGkrXu8yRL4oBLensn-(IL^72@zdR(9+X2Era!9f)PyEr3Ae_;;=}H6YI3bbSk;=YW#eo z)a9ND!UM^*aK`$uKhZu*9aWhQA+&ROOKZNhJhQ$TGsmmHLyKUK*=LKB-Xn*-v4V1+ee+Y70)s_PyVxiGpC? zBRw3+HTQi$m4&z!KlM|J3T)rY^F(98FXZ7k*BYptbPJzYrsVVlG1Z5(@s;QF#0aX> z9!=uk)@^+CTmzE-xw#@|&!FY7NO`TSWW~GOr^ywWj80Z0dn>uX@rgeHal^%BK4{YO$g-}6n zlIYD1`UBhe&d2RQuhULkXR+@w|KNq6A7tL(A1ptmh)E}M_N?;Eo{|Up+OtNMvtBV1 z7hyk%Ivm1-ZqM39b}QYUwS(?;d)C)<-&Tmdn{Y2gTg>stqL{7-?GaicoQ5y}q3QOl z_aEghl=iG+9=EY)MMKaR_N*7q=B2D^&nn?UbbHop3<@C>!)7JySt=pqZ_h$&+uO4~!I%(>7cvx|j;U6Am7{328pxh?OT_J2miqbHv#zn!FOBLKZ>e8% z>{&pHyLORN^G_N=9cNPE`1E}gMN+@AH; zla?wf_N*DRsEWFYz3>sWil#k_tH}1O&PElbJqz56br?4Gte6#S&#GK**t5#5_AHAn ziI*a__N;P?J*zw?+G5X&VHuT_EdlIV^rNOdt2_gbiaiUv25szF0_dNS=< z^kmwz=*hHa(Nhq67JZju&$1ZiFcBYEd)C;uG8~i8Tkj&Aj{7oPGZ7v`C`Wh^;ZuYN z*t0C_H7^PFFm%N8>;t=XC0n*CUB#7#Wvh}bTdRa+3l~}%EMggE=Z?G3PV~H$C6}Gm zP^x&fci6JEvl^Byuhs=RKw3e-vgOr&Vw2TQl90UGAz0ed8%RiAEk%ETgyhvO)E^)r zd9^(K0TPl|o1i~HLh@>J!~>QgJ9W#}OqRgC+S3w`z@p3~5vy3XZbS@e?P?+G*69n( zf&?maJR7pW<_jl~2Fj~l#}TA>OvNU(rmI7!Cy;{7q z^cBHytNF)k;kjO0(+4# zH?pb9t3A#UWcYxQ%`3DJUSVY0k^`HUEPt5x`kDNTq=@rs7h{y6hOY52da?BkEEhaBW2R0O5CpBN2B1?O$Z?hB5@EkEq`7VXt_7S#CX6bFde`OIkl_KvLs>&ts-W zdw7Muu4L2JhZIYyn>4gZ4GmqP-HFNZBn;Dz9;zEMsF2aHXw^^N+K3#bS#|52e~OGa zGTw`D+sH?p?&GEEnQ9OZfJIda$6Xjw&iGZ|DdTh0dp#8bBbXIt6@Xf z@p+hJK;?h1_NKo!9{I5mn+;;%Pk-dO<3RUZ^c8r8Y*6U4Du@kWEHj6;cTKrZ*P>hO zT@%^9PKz`$`USFgT}ESzj0&WDhq^0UO9Nb%_OvJ#DyzLqEL)(t7WS_7L-ZD<(Re`Y zT|Zu@>VBoYYx-L>3govo)!v242P*`_-nH{w{iBHOD)z2^m_Cf=^0jx}xsFCa0DIRi zETly)5Ohd;m&=RwFe#wGlC+n~czvT=H=)>KOGrI*kp$ZWQ?J7cvR_tg@oA_%AVXmO zz%*YS5rS z_OqK1iwXy@pY<6nOQ6qPM9L~>IQFxirv2=cb5#4;r%s(|aCH`=f~Ng!J3lqWe%A7H z8fd!xEYse8cB6*|&lWU-kNqt5K^_$}NVsEk`x&>pVL$s75|v=K(tdUNdeyc8<$L&%^)RbblBb|6mtM*I}N-!SvD{jB&-pA_bMrmrh( z-=jrs>}OroJY1g38^C_{2~a#HX27tYSug`^Kbx>K+Of~}vpzFuz$VGV9u)goTeq?d z{dpQ@TN{p`OF@a`cy``Ntr|91OX_vw~)Q0!;XrPL0U z!hZGx8s-1FdmH$uimQKo6E?EILKY1g1vNrcFn~c&!HDvbRYX=dktkL~v=-N(R%KUE zi4d1mmUR`Y)R$s~M{V^H6f$?IngTP9ex<6n1x`*-axJ=4E$ z@J@WL|EKW>>@8X!lB;GuteVC2RWp505#j(6HVepAGps4ms+kbEINBoeYc{<&MEvWY z5jo$g`FoWl=hyaogNy^-4~XbbdAfY#tY z#CMVX=O1lJUaUn0kX8y?!#aKWiBOE%F1^7p)jX|pd6(YCph?dl?=aDX-D8cGqX8gv zijmnft_W37JtF@mDpa5>ZzRftO)hWmCo!{eAbBj%6VsdhIv@j_=oc?u0mSqZHu2&{h_;wKlBh3=!X8jmH4a z$n0q%{7^mOjM)qvF^b%Z&lFPW6HH+cn7$MJO|vnBUeiL@Og|3mU(#GUrqQ_-XvTII zyV$#r7;bCC0<*x6{XO1(_|2V<75{?bduWdWWhD4{vjQfSSl-t5D9k%94*yrkr4#oH zZHX|x)_4iAZhb9j+|4wCY!*-ZX$0ZTmqt;~W~z{C6;t7U!g$>1+(^w+Kj9ZZfsK)A zFyb4X92rB&e+5toEu+U)u+RsXds=hH4#0|_=I_w1+By?sH#ix9s3qXez?bnNQ`>wXQk*V zTMsxfmW0ck1-Iu$Z)Z?s>|AU9%T)z|Dj4g{-JIcovkAjWnXCQ|U}L9_jh$!&*k~%N zYMz7i9eVl>PIvCaewv1GZZFy~1CLu1h9v6EL+uj15if=(?hB>9fK<{1VViGI5W#(v zb_4p|NJq3w%02cyWmyy99Xc2?k=-o@1=t@Z0;9N}&p2aP!j-DSq4&Nr}-&WDL^A?d zTqwn=);)j0PGa~l0?y|s(|`6-7oXF$gr*$z@%I0R`nUXN$@fkgewnvV1@M+HKfke!}@pJd=jv&q<^=HLHA_TzdLT=DjJ=e^?pkIyE#HTUNl>ofRg$balKOi%4iHt z{U*fkRSCp#gU}tC`i-&rMM_nNRKNVG#Mg@|L$qE8Dr1aD?Ry*adPjx$UuXtMezNvu z)pHXU+mAZ;OXZ90_N08{8dg`n6J!I4y7zUQ#7XVckoLxtnu$z`28_53Y@*dnxXPN6}`&XRvBVSyh;HZ-P#CHurMwWZjEs zcg#L^V0fb5EQ6K>HX;ae#}JOLP~vJRlsxfK6zEB~@>mu6ogqRJ|WB)Ku@Q)QK`~;Z;rbZqvW9T0T)z%dC21 zn(A#M)l0@>z{&b~FRR{FnvP)oum+}x8ovfR!Cwzu4{O#I9N(_nzNDo!eWJ||{cEPf zfs*6vi;S?AV`A7KY#t;pH39S{9mHyx-w#Oeuc7DbYe0cEoic5NG*Aq~op!`T>#lf^ z=_jaI54P=IYmzTsR;OvCO?)zs5UHIf#Fv*COHbq9#=oA-4M->-GxM8ORBes-b6_v;6V?-z@J?=!%`hm^lh zy(b;M_xTijhk^Xe{QbbSI=->^(;5EW_I=mz?Sx!JhhdXT8vd?Y!1#VFiMzA#bIpl| zgP$Acr^D})UIo7k@5qMV;WKsoc2a-T?ClzUKX1>>&;PkW^79)9$6Ye1|&6&%?g!8oqsygXqvGcDbk4*ZoRq_0O8b&e_Jp z-p3yfeX-}xbokwNn}XlfKz3&Q&bV5~ZzuJ|Cwsbv-+qvTO!~rkH}mtz4--ejEc)UT zM8_X`ef;RWbojmbRt3NA+q2HK?4ri0%Sh7oXp$eCF1UNV~+!dQEc zg&xVd9=1xL3g)h$oww!_@P8KrhD)MD(s6LNyBNaf z)AVIlb++x{?Qkc-9~7%?u!8X7S~rCu)7rYD7Ux$XX)Z0YFQn|WU$?F7UQVP~;9ESm zL8*JL|CXG;u(2z|oI$i0>OfFZtC$N%7yZrW8Yw_R3v6x`^YMue>KTUfLg8Q6+kOq> zB#{CK!aYQd&~XM-gNw71w^!R!qsgn|a#}#bOby{NkN*n3o>uK;-CX#n$}iZ@8%$&3 z#SH{MfJE$CD|yYa>$=#ofF>TjTz2n01lWXPzrf;X4BK3*>8yt;JEm1Ow-^xy@#{;; z1Ig(wI~D_MmE!ro;Do_sBHm9z&%RlpbaR zff@~DhtpWcNI~DV%N6*VeJ1#})u)6n1AXBv)aYCBsY+iI(dfJ7lT7rTo!=>-4)96$X_$jH`u#VKp#T-e*Cx!|Ltb@ajIns{UzypYfAYgpGcg(EYdOwI*U}4 zfA5%kj-%~}G{$4~;|aS27=f%L@laVzs-sHm~ z=rbMfgwL$63^~@^3(|gNe-BI!B3p1gbWYsm!}5Nh{vmC@lE2>J7QKKlSk7#Bq;PR` zss6{Khql_(AhWm3mU!FY)_#KCR%2Fz6@P->L84 zIe$avtnbA8EbiL~+a-f{GZ=e?8P_qg9FT*nSbAQ>G!n>4} ze~&-%aOj6eJr5}F!R@d` zZ5?|3dp57@r_#T@XDIk>1+p{q@2@UOgJ08n){;rX7P~qyN49W$erLQ(i6fj7oS(`2 z@vQVmCwiB%;&*-i;lS@la+xm$|Gqd~!S7NaJ2QUIn{39j1AAv!KJTT%D-aL}l-!eCozop>=Afvt%%i<~&x{Zh;}N>9j~VC}_m_-+U!h;zUGnC8 zndsO4VHO|{o_=EhqCvkF_@oqgZ|2P$Y3O%DO8GPVBYe*Qc|7Cp5sqA91w-x;9MDuD z`o{qzKQ7%v0G7uSJB`}{IngEb>TE569~?g9QSxIwJj(c(

3fO!P0P{*0@xjcejV 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 literal 0 HcmV?d00001 diff --git a/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.pdb b/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.c.codeview.pdb new file mode 100644 index 0000000000000000000000000000000000000000..0f2a2fe5ebe3a6b4a47071d6c124344d6b8c65c4 GIT binary patch literal 5373952 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

(`tO^HhP_4o2KeFa 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

ATnl{o_kKL%F@XW90*ugjq}L}m&1ArJR^EG{YU z$tl09_>Xd0!C(GkourL&slXbJUip&+}!^taWREr7k^Y|1RS%>mokZMI1Nd zx5Ez}C{0OuTDRy;;QbMc_ZIw}hrDsUWYU$Q<$U_lJN_XW^T!1DUkJAn+u;`h$A57hOSz+t z{iw~4*$xfm&ew@Jdk~$-exfYb_f04hE!JWjQSeb#3∋vi@<_VP&1aeOdoyd~4mz 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

HplF4k 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

&g->H7&8)+UoMEn(BDGvMd>kCu$QFtqDOE-(8Jm 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

m|50F`4~U>6|CybrKHurF{fFaY=*r~-0`Qw=Nu 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

RFM7?ZruW}J=q^FYD^^4DD6>sclE#jHh%w^Et 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

N+jAI;%_NR-0E5O#IXP zJ8tc+=V7hVo9MZuw$(fJ_!oyB9+BE;`Obe);y%wF`kK?4;8k2lo8gD#!T4^U?F)1i~ z-B6!A!<2_q)RHqXxG zcHG)gFKeFUIsIx&JI`pW$?1G2z36u2)}*mFE*999q?r#pHgS04HoZ+t9Pdq+t|>TC z=Y?kg+^g9vsj|dZGVOyh@0EOx+s3cy_c5{Wu@zPtS${eAuHOrD_YxPYqmvzzCtg4S2G+w&DTfsgyL;3;WSr}s2}BRNAsxA*F(Ll4CF@ftCU z}UMSf5c#wD%9$dwxN*{Zi{ILE|6Y zyh6!Xo!py>dW@pw{1>Y96Glf#u3VPUecGVl)nz78x8!8x;x?R5ys%=x+!BgfNXwP4 zQtQ^`N%~dc4G*7yuckI8i~EOljrDpranr=I9NK~4?i0wZm zBUB|;t3z-f79P@0;axYI6?gh>RitCy8=+ryw`1A6d=@2~Ph`a}t|^ae;}kuIymTt3 z<=z#qTh?RLmm!Kv%UC-<+UJ%|yBboudbrM(!)}+BZr_O)G0JqlM`W`4c*;pf$a(~B zIOR&Mlv}>|!HAgdzERKn+!y(lO;IQLn)k6Ul4`~BtZJ_u=d8Q4q0;Nz6!mdwBifo) zWHh>e!2``adYz~{MQ|g1quQk`YtxJC$4eOL)yFy&yyY3*o5`ISo?W>XadGH;HK)m@ z&E4mJIpNxtHXAjcn9D9dI{x^UR^!wolXeT09%1fFrRC-pKa9F6wC#VQpH6;O2aTXk zu}g0z_M07i?brdi6L~LD*H^UM;VG?af-QS4UXs{9y{F0g{1?6|)%NF73smYhp51J9 z2=}92bUkA1PTvk+_U2{YtNfY#?CI){ci&O6^n2uSApc+q)w=5yJoC|Vvz8AJKbI(X zmGLe6SAEO&I+6ZT5qm|yYkLddgIP1KjU1;oezYV43_PHssyPnTBdh7c2;o8o7 z+9XJATze&DeelV?3;PE5A03BhbXu;z*}7Ts0X~PqZ^_PYG|VZlm-il9{4&{heG<3t z#gkLd;~mogQa*lezVnyi+T9Z?+iuA{G{>E_qWX}c%%<%jo>2p~7#`k=cjUBOW`g9+ z$%BnsjT~-~G5XqrhtJKD~U(_@FU9 zXp9dUra|@f`q`$miw5xt7-ZMO><;J~_){vKbo{%y$b?rf=5X-~iMS&OXZ%%ocyMKHC zr3c@_hK6^PY!>6Iw)DQG{h5X(ER|SZ$sg&fCP%MhCyW?Yy5q*0t6yfbx0Ww3ms?jb zXxKgzskDQ=Jso2MPF;juihIF&bf^G4y9ozFF-9zI@@wIJ`B)Or}`7SPYhs40hW zaW5^W7BwkKT2~Om_{eFt{$MvG1#Jd{8=J-W$o<`Ysxhh+xS3X0hKh$ zCS!2?z2%0Dj=bptZM7R)U&HXde0Y(Fi1{e)68elZQXn@gx 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%0DFiI6yHXJ13i`YWedjKPOEBns(d}4xmCtG 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%0Au zG5)Q!z}^D~hduA{_#fMNS6bg-vBFvudXc_#?zie~(rceTY3tLAfC&tMbaUeysqG(V zxw^Qu{qU zmQP{4|4VCPbs7{@Kmv`v$A4-!Q{0D5=Q7(7t!uiC=~MI zA%pt$PTiee(6?t}Mv4l?rS28Xqd!Pn(Dxw$t|Y9{NPrxc)7@`wuIS*Hd9OkP5rv-iX5#l_Vi9|I_H1vtn~f7ziEkdqf)>B7w$u# zOVI^jv1k^NYTIz#!p`$wbgt?3t(Rek?RV`|+9yqh&gsRI6vE#EXxlJe9z3WZEEe@$ zQYBU&{TLspAJaKwYnfTtVLPJ*()QWHI@qJBlg{6NK-a&tSB)ALTxULl(v!~7hK04d z*ptroxse;`QZ%+dG%FoT(z{rSrcOG4{{fxv8Zx5K;M*G1`;W_Y^qZIT=HP(^_{HJ^=*-7SBT}n*VGZup)|bw`H0GN6bQ<0&$B%g+ zZQDv{+8wEn&ffy)%e_b7?t%hPRXc%Fldg&D3Ty4Lr?#bYO<(E!CU)5Ja@Zej^Z$$Y zc-p`5M-!!j&|1?@LNn4kbbVpxef4ziqr6k;C2e00ja_>?|6kIZ?)5BSy=f9idI#DT zcCIhexk`n7t887h{2YE3KY=g)3uC!Iv>u*Tyg(ZJbXsQvI@g0v)W_-Es$W{|Pw9MC zj+KrtyJCM~>ZJ1*2Gd)rdZgY@g|u)X zhjRN3|EZ6j?uPX^>~(~UbS|?M$~jdzbCmt*y1`+*lkBPjE8_3Skn8HN>#lH4xwL=C zE*t4pLvLrlluNInX|SZ6HJ;_D! zzZw2B)4C3-gF~Aou@M=lB0MX=2WJKe-`^d2CJ6-kcr-_(40 zCuRoNrZl7ByZ!dnq^?Ha3u2yF6(2~BSnnM@;Js2TjJTVo&&)Po)s2ROEf)dv3Aw>f zKl?JXDB85TkgM_Z=a(^ygPCcDthI|S54L0$E|kfS*jBwyC1w$@(m0^95IfU$O9f^z zu;PM^`?HSDEDlDtndLSu9eE=&JfhhsK^0M*m&PVD#NqwN(I z$}f&j*J023bsD|wLzeR+xW7cOk@fRuF$;pV5bUu|v+4FGyPQ$5MuP1w{dGfT^c>(u z!LB~%+3w6t42HIX^?l_y712(UD!QCt*VGAZVWxv|-zEL7YJK->%tBx_h1|Af&+E)0 zU0jM8y}^=Y~0 z9%f0fF=>WwtQD?X{3m8%WHwl^T4(QhhFJoPzE9;uSJgfpebQk`Fz$mzz&;%J`x2JZ zF38Bycch#jjOEaEv|49(qUzPCF?1nEok+?B1Vb~sSP%><+T|phcmIl_?Xk1d41wXF z!+z?pg{s$PVUZ@PR=e~0yD7Y}Sp=*yK9la0c6fEkQOry*m^+(MVmI%v>DY<5VEE`_ z7ET1ya%7)gGgh9#&d$$|6I?IEZo4ryl$nkbTo&q6M}mhO9YR8m;x8#@2v#zSg~3Q? z(vLddx*z)CYEN2supmA&tI+nm&CKFp4+>VI=#@j5g-|%|FO;TiKLd>QBPQ)`7>wJG zm~6iYSOatpF3YHEKf8tVi$h^meiqoh_#(^A{B7_=mJ6XWYNr|bkV`H+e<`zw2Q$H_ z&r+IX@1K3P&;gc}6pFc|kiVzLiLz>uYr--ug}Zeh6?7~49M>k+C%!`DtT4%P&pxtwS1T04muIa{{7 zB)5I^^&^=D!MHw&JrMeZik2!TSUr5^H1BJEe=TMvm`aB@SZ5)3sKTapET>P~FL~Vt_SH%MshNwA~Vxi-BD#*u9Y| zN0?b)T?JdcWc*2Hfl6r4oK#sT%{$FoNF}?ResmVDGh%XV2Efn_Z5@cM{QkLV*x7O+ zFsZ}rStey~voIL`IdZEe72Clq20#@-^+IW$ns#-ZndOmY5{zvm$=%kn<}sF|7uP^V zC(Vb-4PVDB07jjh^K0{N!_CY>U^30bJ%7By%*bNx;w^4u7S3W)E|SHhTog=IpC*{9 zJ}odbucJde+F&4;MXRc=>j0Rlt_?6%ei1NPFS4$qVC2`iK4<=X$Qhd^n5wQV50(V0 zlTH&uQHvbRpU3(I(BZj%5|i;@2#n$+DhsiZYZ6Y}V}QYRI&7iUei;rm3D0sDBUKa@SMX*(?f1j*D3ZUlTGLHj8;M6ReDoTRt!K zjx5U0@{mh-uq4>6BF$UJjHRw+m&HJ!&+SJ#oZs#`XN=Kryi>ce4!1s@-;m{EV8aFb zqz4{g!$#%Q;X%<9j$Fmv3&t`Ff$QU^y#`g@+|ET2uKY!6+VQ{dT_4%ISj?FmU`yX>M+L$pn`3gB2BWcRu-AE;AjB zDv8rPXNdm}W(F8S7>DgnT(^{21gyDWv%Woh7BdTs65%wTT3_oJvmk;qj?bu^1J1jW znnj~_2m`R4pniJ6iH2u0i-2v#0i{Xo=&4>WGcy92_9JF~`(}b!)Pu#rxbKo&*4jCSN=J6jxNITMWX;WT|SzNp76 z0S1%iuqtgzI{n&T7w;+(?CW=4@4<3WFp66^%}c&%?X-~zc5a%%6>9p~UyNb7xCgU5 zSi*xP!HT8pjPeVXIQ|6Zr`2~e{fe)8GxNies>-Q*uz&{(g0Y>TvK(JN^bO9>0Ao8y zOxnS)NRtMotg{Fh`$lT3%T6`S<1|e$Zg*m}x)fT+%mTwdyN!q$M=A13jR!wkxxHYc z&GA1mGr+i1OG`hDELI)(5W znp6vbvHhfd{<%-z&ddO#_=@@B;5FftmPru3TznAH9AqUSnsK?JP4 zkTawG6P#uY>|wz=BqBa$ffku{Xc}W{pX+`vGXt!hkn47){{zfSFoZr%IhQT^{Cj4J zEH=DGzZJ~%C`X^neD<#sD<n_`qs_IxGYihxb7mq<>gNf zW0nMKE7;Yau11ed_3PkunV5mgKdx97d2jIk#WQuhy?;xj2-QX|CAU^a^GPu$Yi5 zy7ob;CM^g5Bj}uC@qyEP{*4_sFe788Vv&w&rXdBT+>L5RKWeFz>x?@PMZ52u_lIqm zY#q8G9`t2&xZuxWH2iJ-qCN4BmD~(#G#NKjq*=(oH8R1jTGs9|X8yhyw<66q+pa+_ zsWgoNSc4R7d|vk_nZ@sPm$Tunmd;p-4{?_>)T(R?ma~Ry+6)|UJB+C~?>=T>1ni`c z!{%NzlUWo@jMFNk*_lgjm)fj(|D-xdsjy;3ig4J z8~6Kd=s~G^3El0Evzo2>?lEQ&Fe(`9(691+sNs}c5H&PVut>Q-DGQC-)&%P$SUq2z ziOl@4Ub0@KoezLf<#K+jr@#I%%SFJ73HJ7a-3ypSJy;B^vXHA4I~8O(D~mOqu+V7- zZL~T+e-RC*dGmyokToCMBQO@?0UwDSg8OmaEPC`$Ns_HWWCVf@M^Y0qW zX_{c$#5j7~`syxbQFy|YqAW{q`t%615PEn>u*$UuO=lJZtAP%{?f2ZR#cpC|A?EoYga@+>b10 zK0;4)XYw2N&9CJ0Y#m~crk=y$ayI$qAZjtiqEj;K*QEQZPS@rzi-WBbZTsWHcNJw8 zecT;SoM=?Tsp~kHN{0kkeI&wV`EL7c$A;+egi`K>XKo(I`319>v~>npO_64c24l`* zxhNRl=Rx}QuHIt@Gjkf&JfJO?rR&i~)V1t7vtZRP$7g0gd|lP)XWCQln5e?ej!(0k z4yFsa1AEpKVip8@K`_1KYp*g(fYlQ$C$i*xW;#-rV_J^efCmeLT`1C&HqrpQKI>39$Etob+QcC{D_9 zeh2EVK8MrvKd1I%VK7-QvW=o(DnFJ0D<<-j{vqkXG*~E=9}8qL>BkH(Res?tCjC() zi^+0EvzU~Nfyq8E{g|1>NUrt)L->&x^GWNyFir?>6o_DjB`_G4zu?Z+Bk zb|Mo)&vN(O9?gd6oTd&&#)k8gek=@ze-8U@)g&5LS`M9i+3m+HbJ91=5?}}=9l7Sq zcYn*wn636>5wLzjZcqNSK`fU9lYZ=;*%RJjmUtca>E&heo8F;HHHW>W9@F%|XIUu2 zx_^DJ?l6|qk@_JVFe_5$+-sTn-*x-3YS&y_ftfZpbDtI2`BU>ha%^h^>`T$M59BU5 z&T^sm)P5`irm{;hu=+@Z%PIX>B1=yCF?wmKDoq_s<;Ox`DnAxpfW9H>^IG%nH(9?3 zqUp;;Ii(*n!O9CJ{g?%&3nu+o5={EBdq3VxLsg^x8C|IMV-}bk({kJzZF}wYvz&QjbctJs{oOz8iLcta$Fi8z&jeHHV1cRZ z68&I?D!xuESKFo73b$R7@pTeR6<_Od54!|53%YWjm+`g!q1!IW_&Nb5?UIbIja43Y z2~6508DA&Cq+OEnbporMs`%PmryhS6m@2-eA3>FNNygVnu%AS|$oM+(xjMe~f1!@A z6PDU8`8TL_2!N^VQaDRa+NEd~lQEbHrm{;3FqK`x&qgTYYyB&=T?&Dz>{1v^7j-S| zQWQ+uB^h4_wy5n=7))iCA|5OXcA+SXv`Z$KD!#V1s_l}0o7yf#z*KfAu-&bLv`fJ( zChbxPOr=8@Ol6m1V5)d2g2-v5s24f!4}RmeOEO-Hf|V9>GF~#lRPhpCk?pceGF~#l zU|t=YCF7+qq9bXSWW1CFyGY2rBsDRAV{@rm{=% z<7&G^7avsdQW)%6q5JV)UJBz-%fWyDN!ToW;FzJ;xr3Z|K7K0md=ACz$3Cfh1} zDB2@J?(D|#UztVmNwP9+&w7BF{(I(GC`$9s<0a-X3!K6AcpPw91{`{y%$r@#2v}t? zN7y#Ck29As|8$r0+Ugzqvs@BPw$a4x)13S$Wfk*#Fx`U%JXkP`)qLx$hFs2&2Q#u* zgEqZ)vs@VL5>YQ3ewuzivsiA9_8ktmK8?>Ve~no*FGtx2O)!;TNr0*1-S}BKO1}~* zl%rfvw!l>Ju2v*R=~qHvvxI&!-lZ2JFA+?}yK%7Lg2{L{cutPeuNYvec-I1xenrN+ zaojAWig%;MbCmN<6HFEFCQ9Te<6Y~*9A&&4FPY=q4^87wt|uqKRO`v{i*j7or{#Kb z60DS{Pw4~vWpb2$B?Knrq+bbVF_~r*OyyVNU@E_ozzZ}~>&f)+!{tH;IS&tjsr*U^ zOc!#}uY|#*Uy<>yze0|3Jvjs>?UIZK4G$IuQ~8xBnDi@^ZXMVe#fJ63bv!*sIS)^Q zsr-sjF-PfFv`RTjzhYjJ<2?77?N^du(swNXzVvD?XQYaoz4O$r*3A5u;yt=hhHc%7 zwI6)VOvlRyRDLB4CjH9T+Eco*Tnt9(DjaZ{(yt`IWE)AplJsCSpjC2y52kytKo*mJ zCFsFISxovB15Emr_Umfj%k>him1Do(lk26d_D~0Ak=p7$7z0!J6$?x?Uoq>b{Yv-> zw_lO-l{lDczLEe_%~t|--F`*RR}x^-ugLjI3@?I^enrk#^!jSQ5(JZeMb1}DFzHw1 zd?j{ej&glB*2HaFrTvV9spcz*rf$C?=PTAVZoeYuEAe2Ca=sF5mZMzX^|w^}l^~e( z4^jsMtiBkVa=sGFl9PTVp2cLE2{4sk@wZa@l>jcu<_Oy(*LQ<$)P5xlrt&LMFkR>; z{fY@D{feBggsxNjl_;3BJ<_klJeUcl@+%gY%C97^SNoMfTeV+_ft3-u%X|6bU@r=` z^0LgcJ4U-4?Qy|w_~7*OIMm3;CBZNiaBTTy7rp$g!`kO4uTzFQsCAEmwGe5_`&bfS z#RQYr)sh}e>j-}&Ul@tWTN7Y#|IS#E_p$i8T>P*f%^uFqON3x&VKj{6{It0N~{vnbjC;dY#i%I_w2UGcnB$#U6;UB1;cLeTG z`v(I|%9|vgHXdl`W6pCE8C2 z{U&xP;;dQegWa+I<_=Rg;;Xiu58S1;=g>R4ZY zz{3uLsbYO2;p{WzHFUXJKQwJnc>sbc*En97#xliYIBmIt$# zwB-hv%9cmLRJPoltd8~L536l?5=>>w{g0?^c>qk>avAGeVD-d!koP3|A9asuIc{|i z764O?=@6LeKL60;u#vt@%pmXcH=fMV=)wW77woJw^dTJD_BsY8+oAdJpPcm`3#^2Y z8{XmWxh$8=Vyg#~oW{)m6xN=EoV-6I4km4#ybfz+FJ_xegWqll3Xr z!J-~4=D|!47WZIQ7L)5>2@jUcVsaf!d&#{HCanovG z)xOdHn%g(Zd5!^AL-Zwizkc*}wQo#-N#7{vIng<8-zeufp*P&VQO>9IiYve^Bny>w||g6AP81d)Qg?2DY|gchjhIT0|` z^_9>fwQr1oseEG$OywIBS#r`h(hokX($vAEO_ulThrm?6F}zeg&xtNm`^Gq!$~Pv! zbWzuGo}(>y`$jp>iGitnV**UtENSPH9!y)I9@9FQ%I8>MGC%2a5?Rbu7LWY=E7d;7 z1XKAO<3qPCmp&&3CVh^)_7Yg_X7bug{3Ex|k=I_VHEN%uuXXzzdF>_iiMyQA=S0C| zeM+Ab^I)b2i+eE3gC(+<^f^fnrhV$xLHZm&nCjX~@H6$bm%w^;{|tetd`<*RH6Js+ zRQnv=a{C-P9}9!2uDwLTRP(U}nDjYvJ{H~J_BnDs7TW0cIdVQ`fhm0snDjYvK4xrk z`y4qR3vE@;$3kDLZEF~;tnfMV-umcHx6hIDvB)=WpCjjE;a%$aSQ1P%AB*o+`Cgj~6g z-*)aVu)rz^R{EMBp5`=@9&-MJYPkTI)NjRzSzS2I2$-szaWIvB{zK|C4Y2OQ_I$kU z$tO9#_~9J;H*~npe(YJSJ+r`3HH#frGymxv4Y#;D?O@J};ZC)5|NPZGRu*2nz7ew^ znAE+!IrR}{5wHnDhpvsgZeZsBJ;(JPiN|-9a_)CCz%IlWSwDF%cmzyUFNrfbu4n4c zZT-hnoL}q@wH&?FzNEsiMyxDzF2kRzu7*X$&b<83;x!P@cnR4!2`plcml0G#v z3agoQPOdgyw$#r(PS+D%7pOuwm4 z+gf1sTTPs%>}Nq3c@;BDshM6jS8FcvyLfi}8C=dVn5rx>4`z8Vt(>~9!xhvlQAy20 zRnVkd;K2+qmCdp` zt68v{nwdS+I%qvT%IU!jFjZY!hMEO$Q!{gbx-1DWRlS7nRI~V9Y8Du#&d&hrA?$pt zTk%)e4#tP)Dt)RpBG-A(EZvWJ{u+})os@qV>F(Fp_dc7tkImwD=epkAH@w{mx}0mX zqzBXQaqH0XymnhzE(E61!5pP7r+hKE1t!OeET?v_JI$5zD>%=f2EZ(Bynv38wB!FmX}6_cv{#w?kY-`F!7L{A3xmo0q<$8d%unj4J>bqy z>KDjjQa=Ms<|p-wgXu!QRocpxj_z5k#@RKT_(hB4y58m0enh9fET@B&6KPJEdX>|! zgC25*hg<|~f=KiF>t{GIw11qsECDc8SwbFiVGp?|n5r!Lcy(EVV5+hh9&!;6xfqzL zEP)5rWeI_)$`baFi+aeJV5+hNC#cI}fT_w7@sNvo$i=}_WeH7Gmn96QDofNu&h(J8 zz*J>1Cgm#EBcoudYhdArbCu5+1s=(D-5(;afknV-2;V5Lftioyy5`~XT_4(%T-SP} zyar~1$$P=&HL&nwxypO}l3=R!NdMGa*LtM91{MKR-Rl>gmaBZmDELgSYfVnByBT0L zMZL&tVA1Kh%4dusFhewnWd9(qfrV%0YN~tvVqmIkVBzO;wTdE5`HWEvOs*?R9pYee zy+GazuD#%vlk1Us7L#cP!Bp#!VKCKtWb~z6TxytoOzX#L7RO=`~Fx54NFxXCbF77Y#{XL;q)nnTKntM#kYYYZh zY0+Qg^XL(Mj(beYYYcHP)tF9z^%MEYYYd?`++$i^ zV+g*Jt9-sAIM3a$W#2WxRM!|H@43gcyv7io?;g|g8iVnEuJZYg1eod?gSk*WrW0VQ zF|939kLe(ol#^rH$YQcyB4Da9ZGx%Bw1te$@_knoMjz>y7rtT306nwUi+#| zglraAk?Z_+0?kF=EI)QHGXrcY4%mjwnDp=$%#vW230CWY8#^%5SLSN33-;Qw%boWY zT3{ClCg0(m1e0TW;jjZ_ZtQaU{cXR zEcQjN)?3K6dG%X*G{a6)v)pOEP^65*j16vf`^h()d1HK|n(3Q!wS!2X`)>8|3-H#E zbYJ=^SEIqf>_~|L(;c=Y*ZF-lYTKn(midZV5=_c%FTcXMPLkZ}mfIBD-;m|3ZEiW^ zn`KQMwmnzdjRP*rjPJkh$}GOa-6tA%ddO+p1emrfPTp*X}hId95G_rb;se zrb;vHAr}ENM7u9Iaph3fFR|0j0zb_d#VoihSL-F@?${G~pIPi%x7_V_j&bf&)pqA< zJ%wDGLQ__=oUzB9X7?2z+{i5cotvGi)|RGc8j{lVAJi&M#qIa)g*)c6TzFru zW(l^c$H+p=g8SWaMNYmEXBIf%maA9o)%%%gKf2|{>>3$mmIT{^11`%AA5@7kvwl*y zZ30ZLyU9M`Kd6?|!Bl-B2qyhQzb|&*%Vh~?vBaj}NM5I(^)y!Wi&owrsFV;%uDSfd8rW(`ni`;T@Oh?PO<>Z)-l+9E6Vxye8jly86 zJ`wYfGr?4S!UB_aSNdY@VmFhvJOC#BrnKcomYlTZQ81M)k7uPRZFv$*Wy|&QY8C=h z`QlIo_n4NpAfUVDq%8Wii=C5inI7 znOSnOjS^t0Hu6_-rzzVg2&QVIum_8Q$uTC!X0)n%j7fiMTz)FcWda}Zv zqBykU`LG9zf?X`+^cU)X%yOm&v%pmMu>`MDGqZ`B>CM!3J_L4~SnrYdB*t5+S)h%Y z#oDU#v%orwdbuXNi7q4B^%-dA_A5QNP9ZmAvycZ1gQ?mmnk6Ui)ilB6I+$GZusm22 ztO3f!zSlQt{X#VsdoRz;{|NlrfNIoC-jP5G{?2$-xFdCz(bjIUdeoV;!k2dgXcTT=Oo-8i(% zqV>#kewUl%?u$Org_$2r<~MfG=)TMXVAtY+>*dKYPyEg-0(O;P7g_mbnZ?1_eo}t9 zn;&pk0!;QZ`J3cguRP}-I+ByWUmO5?PvrM~?fqLgza$vnKS*+c3r_537BVt1EwNR1 z+Ltu#dWnG1Io419Cb9{}@4%$*$lp}b`{X(IgAtSWg9X7jb|WV52Qxh6A|7%vuzN%~ zZ!Gn`)0gyHGkuq0Y1wxJV0?c8v6HPXcGiVMVC0-gcVhDQnZsawEt1#|zMGq2XV;m( zuUl@;`PO;N0$^O9Bv)p2_m0dAu*&IqKe6%ezUcJ9C<2X5ILBq#ebs^SEEn#VrwtSA z`{h%AVU`4|CekeXXoo+U=>zgK>a3h*r(ub=9EL!uW%|AZDoca;h2Lcsz9Uatk)M&f zyWYiZm<7Ul&TqAo+_#C-H011hF~Q!%XU?zb!;jQsW(-9+MSk&h_d54@Mu+EVzl!|6 zYu>~ex6#pg+TwH!M)`Fc`b1$)Gjv~`c9SoY-^H88*Jfsp%lLkhyWwlYNz($O3z}R` z`P<@2uu6jICcT|IrJp`N&v~B*rCB|6rWG>-><%1onoq5-b&Qz>#^Z?O(I{PQ6^9z8n z-6c6`cSB&Z&dzINt;JXD{32jw@R`dg^^1Y2>cv0N-F{EK_3WLTW&li;W(Z7`W*n@! zD9g~1W$JU9{z(}-Px{?F@3I&(15A})1WeUNF)&pdSzxL*(jHQ`Q2f?`f?z5g3^0`r5wN$>DBPE7ubSYD>A=Hz&byqc{p4>0hQat= zKVpxJss1pxZR`=XTmnqhmqL$b<_MJLtTV%3W$})DfWm#r;lm$##77sboL(T$ImStw1R#fztwnLZCz+q}UfT`pXU>vuS zFPCwv_N~d<)W#)#&rhiwq8#6yxAsn#W zv@?GcVWwxvHQ6+IGP8gO3uZCb`vg3g0ai+srS-1T zNFiq1CfT<-*=Z)g*auL($hb#)KI8w0$+%7jWB))*#&sbu_P4}jTo(bOb6ge~*O?yq zSzzpMNnXZvNif_J=A`*i(F2a1kH6$*kI$Up%yXhIXY41XDQ&9>#%pWDE?f67xe~k1 zEHI7>h%N8b@e5{2urX=BLhJ|qerKK&eobB1Q81aNtZNfYRo4kHRbBgESJznp%#ZSM zJIHm0AXrPmau(mdk@bs$srriv#=eSlUw`V5(+(Dx)X!CCU@*&0S$5Bzy3Wb(Esy-b zWSX+hEHG7_X>Y6REC8nJXCW|Eof%-NIy1pkb!LIdI+J}c>B0Q(WPP5}kuxj|sI>>b* z3yj-=UjlOBu~$eN4%Uai>0@hc%P_P11)QH9SU7h;zs z492#c*bB3h^O?oKsGm^V602ghbYeFPEFf6XnvD}UwA0jF5)2<2UFE`!h>l`-F-sFk$w-Rd$5293uZCd2SZ>SCsV!1IN1O@gLB*tJ9B;~ zcVXAHvCM-l&%}e2rtxXn+gUCOb{`Hn&1*}S?7+;wLM;~rQ_01_+KM#q9=l<#ljce_ zGr;-?xj8R9^B&7t9xNEo#O0*l<~Enp?HhKzggsac>|A`0b(ig6g30k9{ZRsJQrZVl zenq?Mb)5WGx$8{E-Z3!te(%AzNDogJ5Bv#H@mIl z)?>^fpJaS0l~elE7+6o7W8K5gJ~5N!v`^h-k@2+-R#C|9`RIyESuO-d3sIcr)O+v! zn3?I3rsa{Qwl3pSNryJu|H$a>!Gd74@I_^zxol*`bKh`TqF|i`E1DSStVbrnDyJF6 zRO>2#{2R;ZpW!-sI*uf!wX1anv*71>+Vwb~{D>WWyw``!qF~(T$%n{!e+;ZxT8@}p zpD@Ajx;Z;dV)tMD>Tc{boYG=n=4n)D%8%IVR~rvvXR`zt-;YA9Z)}94pKf71h%}!) zbilc;7TS=f%}?t`1AWGohp*!_{hKrE(8LYGh%B7 z&l$@svNhv3iAld111pYmoTgmwiG#77pa$4ccdK(vI05!tT8>!%oiiI@XV*()TP8nZ zuKd6r$2rQcF7_KsmVX92TQ0CY6MquB@_OSTW(F9KTVmtKuX>7E1dL;0Vkhp~*^-$F zMiof;(M7Cg3yhP@^c|Ud7KjC6TlX;wfla}Iu7!;H*bh5i*LVLqP2A-zqI;mIUKD5V4t+_LpVm-<7!@M=Y{DbR)AM z7zGfl-^%Zwo5sulD=ygVS!P#e5wMDa#iI=dGBd&0PEdZUCKcPkECI&tPVCgQtK-c4 z->UNqfcf!7F6V76YaU~{AQ&mjtj)U(H#0N9N~9UZnqQqru4fhjBl|~k#O5C^oW*8NTgXkvZxEonTPT;8sJ=K zquQN(lbLZiGae|v+rD{oD6=RS-{(PW*r?jWnZqy^8kInu&OSNPc1-nwPhx@g6;uj07s9+5qUiur$C9>GQ^P0TKED1&#aDJPPmw1m^ z@DDe8;U23KvnW^v(I?KE`b@@t{^{;#`zCM5lm(0ePR{S=Ymz58&A8^%?ht*xYW`*I znFV}4Eh6O3I``s5%uKMk`I$67Kf3iSX2#h*t+inH-Ta1QvrPP04>=1iORrbj&S1Hy z->2Oo%2Idvm5z@~7WZi*h3+F;+_Zw_!Wa6qzCy0uf#f615~Y1kAEb8d->%V7X4*wQ ztw>sqSkJNJRx$IJ^J$ObfMT1guz&ExnfsZ=z_un1!;~qMRuaW>K)cIAHy@6kBqJSw#0~ zhG1Rm^qkHt0oFvY<2zcHWu{m3IqP6lpEJLIJi;slRt^W8U*(RMQ8n3h9R{l?*d3GS zI(|9^R#mX@nqKQz&H|%(3a9z%`hKr6(<=G2W`Zr>V6e-FIdVI`X?i`g_$5B) zHw8(DCXbeK#;sA==h#+a^G~+_jph7ReA>%6;IeGE?S3aNh=c7B?A{BfuVgv1s?T}X z2c@|+r^j>5l3;8ji8U`0r!HyNnSQCePh8nML|ND@2&UsRm*vFVx|EE~j4Zj{-)tn) zZnFp&jUSfF$xpn^EDpxLk;?L1*UHpnwp=nxZtz|Eo%Rbh5yRIcu{M4+g;G*lfMIlw*5BS#l-bt9t|I7Y1vJ1J+%$uGz)R1S7}A?4n^C4>L=G zjTbDMXy>$hq=wJAhlkqeiqL}oESCVQAmr}dxw8c`t)|bJ_mkZ1Cl?=N7W7~du!bVd zF$3SMe?)sbAjE5UAs}yS0u!S(2FnMw1CH=dv}mobev@kc)$bh1~NEo;kp2 z2Ci`T`97mQYr`xACT-Th@xM5+egtf?Nb{OfZ@q90sPKDBX4(M63}_Xum+Pj^uEH!l$)_zlJHvke zqXjJ=Xh=#6JmGWR=|np8e52=s%=BqKXZ?j({Wz&yXJ*<{h#7=_ zWj1H}ZtxkO^9&B9`NZ|@jApt?(bJ= z-Gf==RiD;el%?j;ebt#+ult<2A(ds*l;VS!`RBmCh%~$G2s$xzWS&pENu)XO^+I!4 zE-@edQ|Pe!<=#$TG8XtWytdIPXO#{Qo?$uvBA@n*V8?&%>XgM?g0UiW|8wt?dsr^I z(x>GKxlhYhna?ctA?8k^EWeH#@;bBRD!1-)<`;MROJKFz$8{Ol@=lgB!DPFax!~Dr znT6N*ob__5&!d)a3p4*(cYYtX&F#x91XcnE+eY zvRJ=!#ydJB!E_<_b+b2|xv2kRw1Z%8jh+89r)h$b731*=zw&bby7{w{wBVf|^ z?_b?M$;DGZ@K04j)M$lL9k*t;5OQx)97Yqp)A&W@kJ+@ z8CmRtFKRk*Yd9;vXB(eh%yO|Txu!>Mb96AXuglx z!%mzW1uHGsMSm21mD4mm($v0k&yS|8y4Hy&bTB!l3(Yw|O=jy5^k4?q08y63zubQj z%UNLO3pTS?ul>xDV5Bqax3*MYr~Lw3d>Y)e!`^xHl?5yp1S7-8a z5Eum|oL_@48b+DL!DKlP9eZObvji9gK`i&mt-Yz6r_%h|r;%Z2R&&9j!ORk1(ta-K zkc%iNC6@%dQpovwOw5d-6P~KSRFac%=k{t5@5Ha<*vrQPrq$jSuXg!&-wj7VvT^$=Xzji! zolI{u9*9xpQaOoL+4cT7!o(u`5PM_KY)_BD{BVt7V$%mGBdzPAxbld{g-Q+l4-Ez!eA6w zG3$12uS(1kV5AVU6PJ&1#&qb%%-9U#I}2-^EX#6HFbaZLuKvi6&M?z|%Ji2YP7XS7 zy<;OIV04b<>UQex#4m9$t~2`1;w$U4!A_%g_a9U<1FRjs!)exgtZ**NnP8&?D^vHn z_n8F_x%KOPXEDb=gu$o+In5J&7rer92{2VT1BZRiHPavjd_|^S$8shZw>z=DoiC#* zOzHQt&$$yW|@!=6~Gt-hjEh5;^&ms>ni-55W z3F74N_1Z~h39##N!1=A)Q*sisz>&;4Ll7s2HhtwCW)ZNqIAFPfqZc~k$ns$N(ag0h zN^|a|M=eg%0HY4cX@1eLrBi27Ffz2vWSu3zS_x)+RhLYjMim!0re+ZjW_d9E7Y`l4 z>WH$eec%I=%Mt_QHRB*omh3UnvDX$D*(%m=z=$a;Sk8Z3Ef)kEB;>}OzQGxrCfJ*T z?LT05SG!(}6PY+Ui0>>t{7M(>Y!(KiLCj_OwbhDqnI*w;QL)T6G(dErD2KW7dT9nGmAYPUQK4$W@Z+9s$|6j%&aVS z)2DN(XtrE3i*4Qc6m@r-`G0elrBq&-II}<&E7|Wbq?$+s*%e zpKo>FN<(ruWve=B^=k1w=vRK!bT1;UU&SK;B4Goz^ zvsm*#d!Jxtf>DR$aocT8l~c_8fBKwf=YlvXpPdVWk&|J$=g zzH_~}InI5N^Uh&rL9mKAp!y^>$=c}n=`dJv!8)yb<2ROzW~Djsy2WdmSzy$$C`}r8 zl`8bf#H}7I3C4YwbgT=rofM7Y- zGe%$m!FtSI@7Ux77`GplMZTjz%g=Y#rHE}@9J~!XjT8xhjm4hxyP(BfCw?)({DR5n z(c@qn1Z&m$+739h(~O;!8Ap^~x8V&xXBN+5a*QRwc#M&p9AlwE`ObJJmV0rF_c_f7 z*d;h%9ptmeCYUNsy>Pzs?i)&T-&@n;oMsqIM+I@3l??NHX3-+~&b*4`+CEUb4YLFo z+Yn+>KkaOFS;AoCL^;3qKTmhYLljJvrs7eE)h&VAEy`1cVc}ii+r{$1jcK| z#N@MO5inJLF);QWBqyIOi)ZEcYo*qXA4`HY7Uk^ua}mc52F}a)4oXu#2NnWjA3#j{ zfG`-_a$?d4L_Oq84>=3$9#Kx$`+JIclm$##77sboL(T$Imc{Q;7BFR5JmgFdISWi# zmh(Nz0;VjBhn(plXMripazVaxe@IKTW0g~dR$^z5%_JC2G-w zVs9RQHpnar#`oP5tN87UJ(5Ro}XkExG3Mbjz{^)=hZ@B?Bj?@A7^;TMZjcPrPR@qO0e*p5k$ zbD9Pi_cKbfe0*;SW+qr^At!B!1$MDuEhpbVS=jZN1Y`R`X-fNo;M>&>uRPRvGs}g* zWZTNMwFsDO2RYX^!Km+%eiW2mxx7L%PE)IssTX3kx)fT+Ob3hNfaN|tui0(POt5za z+i=^I>zNr>Wa@>|l=Tt;V;f1#Wh23=i8Q5tNif!rwK$=E?+(s$@!D!HJCoB=jLlvA$TB*7}C84a$Pk;8?sv+Gk2<~#Q; z6FaqT#Rg_tv&=k>m_GQe?#zN<97ht{xAhIm!cH>=#_gnfaR|X2?m^C$Y1e zmZRaHDocw@pCC5+=&94pLST2{fZBoBffr}jVHO9wTCktW#TPTvTB=#lgGIm^i!_&A z_WX~WW*m&lz-96ISJTk3b?~>!cb?6q?^K>R^d4q$uogIAxoSXN2?E+2bVQ1%OfKf$In(eTky(M}jvltlJIA-ycpN(af1f%aWd(Dc^VHUhL zGY_Zl{MdL54dYaPS*+wQc}1B;z*eQ(mgHKNn&s3>=sI^BtS*i64ZQ)d*Iy|TCE31(pr76;?;PI7Y1D&fJjw)xIFG|7c$-07@c7+_6sj><`_ zX4jXuVwchZ>|DX*bNZ$Si+eE3gC#sz(t~O3uuhw9BhulMmeKE6hfsSpi*?AXN0MBL z?s_Mdv%s)?@6^kUjg~w8%<80;({94LX?{lT**$%xa+>~bnLbGQ$+fNk7{_PCWPBC^ zy9DRBjpSNT1gxrHaxKUNt09szhtBJAw`66xVC zr)v%bHW=Sy9i(5;d#dXt2&SqR158yfQ7~1##KBbclJv;W-%DLD0Wej)L=AU2Wxd3~ zRP_?*lUd`Wx|Z*64P~*aWwtsoN*JuTsB3wxJPIc3Q@&%#1S8|kZRC3QsYiZEkNo_% zs`Cqg$^2aFgB~mlR#uc##vxHKo{LhQ$vDLHkh47Gl3*N%P?|ChiS$*MB?hJ{OWZ>) z;UTBprY=hqjOUacP|hzGSNR${du+zRYT`4sEwM{)*`;G=vn1GK_{^;TLr*v?($Ae{ zu?nx&W;qi~m1Y7=rn#)wRA*fy+&|yB50}dF{NUA&pN@fz5M|kV<}sR{+2zy+nbw~gK?iH_Q)SS>oSXiQ6R_q)$+F;#VigMNc)bCI2qbs)$!rU+cS2Fn6%ga zfteVE*m+M)?8Iq?z((VM@(W@A>6yxpGqb?X7i`0mANOOH1fvBBmisgR>kZ5Tceq)b zz(O*8cD;nbc&&@_JJa)&6KjO-bj$f}Xgr(cqF|Tefb*+-ptBR(#IxAez?^L?mjt_9 z$oWez8pli@l&_IOoMzSj+jVA9F#001vo9J)Q+!(oeQ>@;oq*Zcqsf)bEU?Q2TP1!| zNxLgE4=3Fl2Zj!1xhPnDA-B2g;2F#;u)%^!e-s>|W+s>}5-;?m`7Q_ zlx6Xd3xg@k;*q9*xJOyQlx6Xd3xlx_pt_bmKpT;X%WnXizbo@hlMZI4>yucm*E;sW z&hGOTSot&~<00Q!l?3D1o0xoOl{PXTXVA}Z&+|?8r_`Su+JQmT?t{b@G+gi6kIh`~p!^>2 z4SSne2&^#oM;4rf|SP>y7f3Ls-BcH)(_Ij}TDVEdkQ?sxK zi-YkzmFlzc=a((xG@}pXYj2|iaDG#!tf{~(IL@8lyCJzT}V5RXr&Tq)x$KPkUga^|e&5XY;5Rl_f z2fH9$*Tf=wi$2L|2B&1!JctD+RdCi4qG0#GQpJmV7;P?STd=PhKWiSdBpCZKVvDL= z_Xsop+xZ%mo#eV>KVrW@Qw9yyuZ6*CVb84I+qq;iZ59LL@kfJs>$DQXm?gl-fRP-r zo?E`#%S?MGGyaGTUeLK3GaZa7kmbrOx^XtMAebt@h)0?+Fn+$D^82A%wfdZ~`!aO=6EdcI_y_#7rUAn@*-TW+QP-a>QPF?m6m;wp`$Y%$&=>x%1my=d?q} zgN3u0oU28%n036$@0_0rRvHIX7RqnSAD_grv&&+Eag1W%+@R`XopGB0yBgCTS!9LwjxdiV34wzD&{D_J)Git7)r3bDoCsn&$ebwIl}q`0PgYCUH2!Q}kf zyv$RY&3rJ}vXq%Nn#~5Ig%0N@-~Tyac_fpc@48^LP~|xJ`K}j6gEyP}d{;S?c7A49 zTKQRFY2{~!rInuxR!}O7{JhQ+!hEm-27euTA^yp?AE#lX&~>XE�`yH&j2ePNiZW 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 Rh)f_dfye|R6Zrooa2?)35byv1 literal 0 HcmV?d00001 From d845a118c4be0b2083d1961bcbdba767aeae2582 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Thu, 16 Dec 2021 15:36:20 -0800 Subject: [PATCH 02/10] re-run baseline --- .../Expected/BinSkim.win-x64.ni.dll.sarif | 331 ++++++++--------- .../Expected/BinSkim.win-x86.ni.dll.sarif | 331 ++++++++--------- .../Expected/Binskim.linux-x64.dll.sarif | 321 ++++++++--------- .../Expected/Binskim.win-x64.RTR.dll.sarif | 331 ++++++++--------- .../Expected/Binskim.win-x64.dll.sarif | 321 ++++++++--------- .../Expected/Binskim.win-x86.RTR.dll.sarif | 331 ++++++++--------- .../Expected/Binskim.win-x86.dll.sarif | 321 ++++++++--------- ...rupted_Native_x86_VS2013_Default.exe.sarif | 1 + ...ore_RTR_linux-x64_VS2019_Default.dll.sarif | 331 ++++++++--------- ...tCore_RTR_win-x64_VS2019_Default.dll.sarif | 331 ++++++++--------- ...tCore_RTR_win-x86_VS2019_Default.dll.sarif | 331 ++++++++--------- ...NetCore_linux-x64_VS2019_Default.dll.sarif | 331 ++++++++--------- ...otNetCore_win-x64_VS2019_Default.dll.sarif | 331 ++++++++--------- ...otNetCore_win-x64_VS2019_Default.exe.sarif | 331 ++++++++--------- ...otNetCore_win-x86_VS2019_Default.dll.sarif | 331 ++++++++--------- ...InteropAssemblyForAtlTestLibrary.dll.sarif | 321 ++++++++--------- .../Expected/ManagedResourcesOnly.dll.sarif | 321 ++++++++--------- ...aged_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif | 331 ++++++++--------- ...anaged_AnyCPU_VS2017_Prefer32Bit.exe.sarif | 331 ++++++++--------- .../Managed_x64_VS2015_FSharp.exe.sarif | 331 ++++++++--------- ...VS2019_CSharp_DebugType_Embedded.dll.sarif | 331 ++++++++--------- ...x64_VS2019_CSharp_DebugType_Full.dll.sarif | 331 ++++++++--------- ...x64_VS2019_CSharp_DebugType_None.dll.sarif | 321 ++++++++--------- ..._VS2019_CSharp_DebugType_PdbOnly.dll.sarif | 331 ++++++++--------- ...VS2019_CSharp_DebugType_Portable.dll.sarif | 331 ++++++++--------- ...x64_VS2019_VB_DebugType_Embedded.dll.sarif | 331 ++++++++--------- ...ged_x64_VS2019_VB_DebugType_Full.dll.sarif | 331 ++++++++--------- ...ged_x64_VS2019_VB_DebugType_None.dll.sarif | 321 ++++++++--------- ..._x64_VS2019_VB_DebugType_PdbOnly.dll.sarif | 331 ++++++++--------- ...x64_VS2019_VB_DebugType_Portable.dll.sarif | 331 ++++++++--------- .../Expected/Managed_x86_VS2013_Wpf.exe.sarif | 331 ++++++++--------- .../Managed_x86_VS2015_FSharp.dll.sarif | 331 ++++++++--------- .../MixedMode_x64_VS2013_Default.dll.sarif | 331 ++++++++--------- .../MixedMode_x64_VS2013_NoPdb.exe.sarif | 231 ++++++------ .../MixedMode_x64_VS2015_Default.exe.sarif | 331 ++++++++--------- ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 331 ++++++++--------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 331 ++++++++--------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 331 ++++++++--------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 231 ++++++------ .../MixedMode_x86_VS2013_Default.exe.sarif | 331 ++++++++--------- .../MixedMode_x86_VS2013_MissingPdb.dll.sarif | 231 ++++++------ .../MixedMode_x86_VS2015_Default.exe.sarif | 331 ++++++++--------- ...ve_ARM_VS2015_CvtresResourceOnly.dll.sarif | 321 ++++++++--------- .../Native_x64_VS2013_Default.dll.sarif | 331 ++++++++--------- ...ve_x64_VS2015_CvtresResourceOnly.dll.sarif | 321 ++++++++--------- .../Native_x64_VS2015_Default.dll.sarif | 331 ++++++++--------- ...ve_x64_VS2019_Atl_NoPdbGenerated.dll.sarif | 231 ++++++------ ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 331 ++++++++--------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 331 ++++++++--------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 331 ++++++++--------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 231 ++++++------ .../Native_x64_VS2019_SDL_Enabled.exe.sarif | 331 ++++++++--------- ...tive_x64_VSCode_Rust_DebugInfo_0.exe.sarif | 331 ++++++++--------- ...tive_x64_VSCode_Rust_DebugInfo_1.exe.sarif | 331 ++++++++--------- ...tive_x64_VSCode_Rust_DebugInfo_2.exe.sarif | 331 ++++++++--------- .../Native_x86_VS2012_SDL_Enabled.exe.sarif | 331 ++++++++--------- .../Native_x86_VS2013_Default.exe.sarif | 331 ++++++++--------- .../Native_x86_VS2013_PdbMissing.exe.sarif | 231 ++++++------ .../Native_x86_VS2013_ResourceOnly.dll.sarif | 331 ++++++++--------- ...Native_x86_VS2015_AtlProxyStubPS.dll.sarif | 331 ++++++++--------- ...ve_x86_VS2015_CvtresResourceOnly.dll.sarif | 321 ++++++++--------- .../Native_x86_VS2015_Default.exe.sarif | 331 ++++++++--------- .../Native_x86_VS2015_Default_Debug.dll.sarif | 331 ++++++++--------- ...ve_x86_VS2017_15.5.4_PdbStripped.dll.sarif | 231 ++++++------ .../Native_x86_VS2019_SDL_Enabled.exe.sarif | 331 ++++++++--------- .../Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif | 331 ++++++++--------- .../Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif | 261 +++++++------- .../Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif | 231 ++++++------ .../Expected/Uwp_ARM_VS2017_VB.dll.sarif | 331 ++++++++--------- ...wp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif | 331 ++++++++--------- .../Uwp_x64_VS2015_DefaultBlankApp.dll.sarif | 261 +++++++------- .../Uwp_x64_VS2015_DefaultBlankApp.exe.sarif | 231 ++++++------ .../Expected/Uwp_x64_VS2017_Cpp.dll.sarif | 331 ++++++++--------- .../Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif | 331 ++++++++--------- .../Uwp_x86_VS2015_DefaultBlankApp.dll.sarif | 261 +++++++------- .../Uwp_x86_VS2015_DefaultBlankApp.exe.sarif | 231 ++++++------ .../Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif | 331 ++++++++--------- .../Wix_3.11.1_VS2017_Bootstrapper.exe.sarif | 331 ++++++++--------- .../Expected/clang.default_compilation.sarif | 321 ++++++++--------- .../Expected/clang.elf.objectivec.dwarf.sarif | 331 ++++++++--------- .../Expected/clang.execstack.sarif | 321 ++++++++--------- .../Expected/clang.execstack.so.sarif | 321 ++++++++--------- .../Expected/clang.immediate_binding.sarif | 321 ++++++++--------- .../Expected/clang.no_immediate_binding.sarif | 321 ++++++++--------- .../Expected/clang.no_stack_protector.sarif | 321 ++++++++--------- .../Expected/clang.noexecstack.sarif | 321 ++++++++--------- .../Expected/clang.noexecstack.so.sarif | 321 ++++++++--------- .../Expected/clang.non_pie_executable.sarif | 321 ++++++++--------- .../Expected/clang.object_file.o.sarif | 321 ++++++++--------- .../Expected/clang.pie_executable.sarif | 321 ++++++++--------- .../Expected/clang.relocationsro.sarif | 321 ++++++++--------- .../Expected/clang.relocationsrw.sarif | 321 ++++++++--------- .../Expected/clang.shared_library.so.sarif | 321 ++++++++--------- .../Expected/clang.stack_protector.a.sarif | 1 + .../Expected/clang.stack_protector.sarif | 321 ++++++++--------- .../Expected/clang.stack_protector.so.sarif | 321 ++++++++--------- .../clangcl.pe.cpp.codeview.exe.sarif | 339 +++++++++--------- .../Expected/gcc.default_compilation.sarif | 321 ++++++++--------- ...rongsspbuffersize8+fnostackprotector.sarif | 331 ++++++++--------- .../Expected/gcc.execstack.sarif | 321 ++++++++--------- .../Expected/gcc.execstack.so.sarif | 321 ++++++++--------- .../Expected/gcc.fortified.sarif | 321 ++++++++--------- .../Expected/gcc.gsplitdwarf.5.dwo.sarif | 331 ++++++++--------- .../Expected/gcc.gsplitdwarf.5.sarif | 331 ++++++++--------- ...oworld.4.o.no-stack-clash-protection.sarif | 331 ++++++++--------- ...oworld.5.o.no-stack-clash-protection.sarif | 331 ++++++++--------- .../gcc.helloworld.execstack.5.o.sarif | 331 ++++++++--------- .../Expected/gcc.helloworld.nodwarf.sarif | 321 ++++++++--------- .../gcc.helloworld.noexecstack.5.o.sarif | 331 ++++++++--------- .../Expected/gcc.immediate_binding.sarif | 321 ++++++++--------- .../gcc.no_fortification_required.sarif | 321 ++++++++--------- .../Expected/gcc.no_immediate_binding.sarif | 321 ++++++++--------- .../Expected/gcc.no_stack_protector.sarif | 321 ++++++++--------- .../Expected/gcc.noexecstack.sarif | 321 ++++++++--------- .../Expected/gcc.noexecstack.so.sarif | 321 ++++++++--------- .../Expected/gcc.non_pie_executable.sarif | 321 ++++++++--------- ...objcopy.stripall.addgnudebuglink.dbg.sarif | 331 ++++++++--------- ...gcc.objcopy.stripall.addgnudebuglink.sarif | 321 ++++++++--------- .../Expected/gcc.object_file.o.sarif | 321 ++++++++--------- .../gcc.pe.objectivec.dwarf.exe.sarif | 231 ++++++------ .../Expected/gcc.pie_executable.sarif | 321 ++++++++--------- .../Expected/gcc.relocationsro.sarif | 321 ++++++++--------- .../Expected/gcc.relocationsrw.sarif | 321 ++++++++--------- .../Expected/gcc.requiredsymbol.4.o.sarif | 331 ++++++++--------- .../Expected/gcc.requiredsymbol.5.o.sarif | 331 ++++++++--------- .../Expected/gcc.shared_library.so.sarif | 321 ++++++++--------- .../Expected/gcc.stack_protector.a.sarif | 1 + .../Expected/gcc.stack_protector.sarif | 321 ++++++++--------- .../Expected/gcc.stack_protector.so.sarif | 321 ++++++++--------- .../Expected/gcc.unfortified.sarif | 321 ++++++++--------- .../Pass/clangcl.pe.cpp.codeview.exe | Bin 0 -> 1178624 bytes .../Pass/clangcl.pe.cpp.codeview.pdb | Bin 0 -> 6270976 bytes 132 files changed, 20199 insertions(+), 20069 deletions(-) create mode 100644 src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.exe create mode 100644 src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.pdb diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif index 6c43d65db..bb6cbc52c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -923,20 +920,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1063,20 +1060,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1091,20 +1088,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1125,17 +1122,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1147,17 +1144,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1169,17 +1166,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1194,17 +1191,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1219,17 +1216,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1241,17 +1238,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1263,17 +1260,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1285,17 +1282,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1307,17 +1304,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1329,17 +1326,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1351,17 +1348,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1379,17 +1376,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1401,17 +1398,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1423,17 +1420,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1445,20 +1442,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1473,20 +1470,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1504,20 +1501,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1529,20 +1526,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1563,20 +1560,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1588,20 +1585,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1616,20 +1613,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif index 2ff88948d..1f7827462 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -862,17 +859,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -887,20 +884,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -918,20 +915,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -946,20 +943,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1030,20 +1027,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1095,17 +1092,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1117,17 +1114,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1139,17 +1136,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1189,17 +1186,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1211,17 +1208,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1233,17 +1230,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1277,17 +1274,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1299,17 +1296,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1321,17 +1318,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1418,20 +1415,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1449,20 +1446,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1474,20 +1471,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif index 96bd3efce..8eb5f44e6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif @@ -772,13 +772,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -790,20 +787,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -815,20 +812,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -843,20 +840,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -874,20 +871,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -902,20 +899,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -955,20 +952,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -989,20 +986,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1020,20 +1017,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1045,20 +1042,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1076,20 +1073,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1163,17 +1160,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1185,17 +1182,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1207,17 +1204,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1232,17 +1229,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1257,17 +1254,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1279,17 +1276,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1301,17 +1298,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1323,17 +1320,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1417,17 +1414,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1439,17 +1436,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1461,17 +1458,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1486,20 +1483,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1517,20 +1514,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1542,20 +1539,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1570,20 +1567,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1646,6 +1646,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif index 62462cbb0..be14e14d1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -923,20 +920,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1063,20 +1060,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1091,20 +1088,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1125,17 +1122,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1147,17 +1144,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1169,17 +1166,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1194,17 +1191,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1219,17 +1216,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1241,17 +1238,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1263,17 +1260,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1285,17 +1282,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1307,17 +1304,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1329,17 +1326,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1351,17 +1348,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1379,17 +1376,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1401,17 +1398,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1423,17 +1420,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1445,20 +1442,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1473,20 +1470,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1504,20 +1501,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1529,20 +1526,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1563,20 +1560,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1588,20 +1585,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1616,20 +1613,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif index 57417ded1..bb317f7e7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif @@ -772,13 +772,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -790,20 +787,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -815,20 +812,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -843,20 +840,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -874,20 +871,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -902,20 +899,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -955,20 +952,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -989,20 +986,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1020,20 +1017,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1045,20 +1042,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1076,20 +1073,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1163,17 +1160,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1185,17 +1182,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1207,17 +1204,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1232,17 +1229,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1257,17 +1254,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1279,17 +1276,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1301,17 +1298,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1323,17 +1320,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1417,17 +1414,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1439,17 +1436,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1461,17 +1458,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1486,20 +1483,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1517,20 +1514,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1542,20 +1539,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1570,20 +1567,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1646,6 +1646,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif index be4a16ba1..e43aaf0d1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -862,17 +859,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -887,20 +884,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -918,20 +915,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -946,20 +943,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1030,20 +1027,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1095,17 +1092,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1117,17 +1114,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1139,17 +1136,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1189,17 +1186,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1211,17 +1208,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1233,17 +1230,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1277,17 +1274,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1299,17 +1296,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1321,17 +1318,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1418,20 +1415,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1449,20 +1446,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1474,20 +1471,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif index 8efdebd1d..92dda9ce4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -839,20 +836,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -870,20 +867,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -898,20 +895,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1013,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1038,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1106,17 +1103,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1128,17 +1125,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1222,17 +1219,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1310,17 +1307,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1382,17 +1379,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1404,17 +1401,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1597,7 +1594,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1642,6 +1642,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif index 1ed0528af..657da81f3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif @@ -50,6 +50,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif index 55823c135..737c671a7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif @@ -795,13 +795,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -838,20 +835,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -897,20 +894,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -925,20 +922,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -950,20 +947,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -978,20 +975,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1012,20 +1009,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1043,20 +1040,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1152,20 +1149,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1186,17 +1183,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1208,17 +1205,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1280,17 +1277,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1302,17 +1299,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1437,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1459,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1593,20 +1590,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1621,20 +1618,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1652,7 +1649,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1677,6 +1677,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif index f946b8c9a..ee7b4cd70 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif @@ -795,13 +795,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -838,20 +835,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -897,20 +894,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -925,20 +922,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -950,20 +947,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -978,20 +975,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1012,20 +1009,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1043,20 +1040,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1152,20 +1149,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1186,17 +1183,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1208,17 +1205,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1280,17 +1277,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1302,17 +1299,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1437,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1459,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1593,20 +1590,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1621,20 +1618,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1652,7 +1649,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1677,6 +1677,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif index 5eeb6b548..9f25db574 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif index c7076a5bf..ddcf41a4f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif @@ -795,13 +795,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -838,20 +835,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -897,20 +894,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -925,20 +922,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -950,20 +947,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -978,20 +975,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1012,20 +1009,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1043,20 +1040,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1152,20 +1149,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1186,17 +1183,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1208,17 +1205,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1280,17 +1277,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1302,17 +1299,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1437,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1459,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1593,20 +1590,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1621,20 +1618,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1652,7 +1649,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1677,6 +1677,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif index cdf60b472..3cb656772 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif @@ -795,13 +795,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -838,20 +835,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -897,20 +894,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -925,20 +922,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -950,20 +947,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -978,20 +975,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1012,20 +1009,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1043,20 +1040,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1152,20 +1149,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1186,17 +1183,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1208,17 +1205,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1280,17 +1277,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1302,17 +1299,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1437,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1459,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1593,20 +1590,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1621,20 +1618,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1652,7 +1649,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1677,6 +1677,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif index e22dcf742..4cb3fc583 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -835,17 +832,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -860,20 +857,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -891,20 +888,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -919,20 +916,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -950,20 +947,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -975,20 +972,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1000,20 +997,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1028,20 +1025,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1062,17 +1059,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1084,17 +1081,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1106,17 +1103,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1131,17 +1128,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1156,17 +1153,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1178,17 +1175,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1222,17 +1219,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1316,17 +1313,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1338,17 +1335,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1382,20 +1379,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1410,20 +1407,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1438,20 +1435,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1469,20 +1466,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1494,20 +1491,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1528,20 +1525,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1559,20 +1556,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1584,20 +1581,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1612,20 +1609,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif index d0f304d5f..9a11763c7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif index 300460d03..a548c6db5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -839,20 +836,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -870,20 +867,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -898,20 +895,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1013,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1038,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1106,17 +1103,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1128,17 +1125,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1222,17 +1219,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1310,17 +1307,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1382,17 +1379,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1404,17 +1401,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1597,7 +1594,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1642,6 +1642,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif index 376d42a07..424eccf83 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif @@ -771,13 +771,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -789,20 +786,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -814,20 +811,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -842,20 +839,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -873,20 +870,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -901,20 +898,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -954,20 +951,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -988,20 +985,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1019,20 +1016,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1044,20 +1041,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1162,17 +1159,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1184,17 +1181,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1206,17 +1203,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1231,17 +1228,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1256,17 +1253,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1278,17 +1275,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1300,17 +1297,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1322,17 +1319,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1344,17 +1341,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1366,17 +1363,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1388,17 +1385,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1438,17 +1435,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1460,17 +1457,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1516,20 +1513,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1541,20 +1538,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1569,20 +1566,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1645,6 +1645,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif index b44604fdf..f2d68c0aa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif @@ -785,13 +785,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +800,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +825,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -856,20 +853,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -887,20 +884,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -915,20 +912,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -940,20 +937,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -968,20 +965,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1002,20 +999,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1033,20 +1030,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1058,20 +1055,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1092,17 +1089,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1114,17 +1111,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1136,17 +1133,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1161,17 +1158,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1186,17 +1183,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1208,17 +1205,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1252,17 +1249,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1274,17 +1271,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1318,17 +1315,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1418,17 +1415,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1443,20 +1440,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1474,20 +1471,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1505,20 +1502,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1527,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1555,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1580,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1608,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,7 +1639,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1667,6 +1667,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif index 9e46dd05b..42594fd5a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +856,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +915,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +940,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +968,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1089,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1123,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1145,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1167,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1192,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1217,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1239,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1261,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1283,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1327,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1349,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1377,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1399,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1421,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1449,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1474,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif index 3a5b828e6..746bbff38 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -833,20 +830,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -861,20 +858,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -920,20 +917,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -945,20 +942,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -973,20 +970,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1063,20 +1060,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1088,20 +1085,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1116,20 +1113,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1172,17 +1169,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1194,17 +1191,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1219,17 +1216,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1310,17 +1307,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1354,17 +1351,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1376,17 +1373,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1404,17 +1401,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1426,17 +1423,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1448,17 +1445,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1476,17 +1473,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1501,20 +1498,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1532,20 +1529,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1563,20 +1560,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1588,20 +1585,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1616,20 +1613,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif index 8542a50c3..409780d31 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif index 0c6ea83fa..425c672a8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif index 41f311b97..5e422baa5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -839,20 +836,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -870,20 +867,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -898,20 +895,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1013,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1038,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1106,17 +1103,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1128,17 +1125,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1222,17 +1219,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1310,17 +1307,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1382,17 +1379,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1404,17 +1401,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1597,7 +1594,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1642,6 +1642,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif index d8dc2e5b8..c4762c40d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif index baace4b16..07122911d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif index 0520c9879..ae31c8c2f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif index d2d9e2629..5451af733 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif index ae52f39d6..28542b0c5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -839,20 +836,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -870,20 +867,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -898,20 +895,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1013,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1038,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1106,17 +1103,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1128,17 +1125,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1222,17 +1219,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1244,17 +1241,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1266,17 +1263,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1288,17 +1285,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1310,17 +1307,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1382,17 +1379,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1404,17 +1401,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1597,7 +1594,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1642,6 +1642,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif index 6e6aafd03..bff3c2ac8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif index f803bb07c..8838bed96 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -921,20 +918,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -946,20 +943,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1064,20 +1061,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1173,17 +1170,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1198,17 +1195,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1223,17 +1220,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1245,17 +1242,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1267,17 +1264,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1289,17 +1286,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1311,17 +1308,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1333,17 +1330,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1355,17 +1352,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1402,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1427,17 +1424,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1586,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1614,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif index 8118c6ca6..5bdec020b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +856,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +915,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +940,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +968,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1089,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1123,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1145,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1167,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1192,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1217,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1239,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1261,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1283,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1327,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1349,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1377,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1399,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1421,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1449,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1474,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif index 98061a657..a90dc7ec7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +856,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +915,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +940,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +968,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1089,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1123,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1145,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1167,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1192,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1217,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1239,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1261,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1283,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1327,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1349,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1377,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1399,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1421,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1449,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1474,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif index 95a41397e..6b7d4c235 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif @@ -789,13 +789,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -810,20 +807,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -841,20 +838,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -894,20 +891,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -922,17 +919,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -947,17 +944,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -969,17 +966,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -991,17 +988,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1013,17 +1010,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1035,17 +1032,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1057,17 +1054,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1079,17 +1076,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1107,17 +1104,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1129,17 +1126,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1151,17 +1148,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1173,20 +1170,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1198,20 +1195,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1229,17 +1226,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1254,20 +1251,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1282,20 +1279,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1313,20 +1310,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1344,20 +1341,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1369,20 +1366,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1397,20 +1394,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1431,20 +1428,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1462,20 +1459,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1487,20 +1484,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1509,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1602,17 +1599,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1624,17 +1621,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1646,7 +1643,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1671,6 +1671,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif index 84d8f59c3..61a2ac74f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif @@ -548,13 +548,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -569,20 +566,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -594,20 +591,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -622,20 +619,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -650,17 +647,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -675,17 +672,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -697,17 +694,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -719,17 +716,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -741,17 +738,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -763,17 +760,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -785,17 +782,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -807,17 +804,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -835,17 +832,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +854,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -879,17 +876,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -901,20 +898,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -929,20 +926,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -960,20 +957,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1019,20 +1016,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1134,7 +1131,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1179,6 +1179,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif index c7a7030bc..5e2b8f9df 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -808,20 +805,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -833,20 +830,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -861,20 +858,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -889,17 +886,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -914,17 +911,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -936,17 +933,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -958,17 +955,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -980,17 +977,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1002,17 +999,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1024,17 +1021,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1046,17 +1043,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1074,17 +1071,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1096,17 +1093,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1118,17 +1115,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1140,20 +1137,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1165,20 +1162,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1196,17 +1193,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1221,20 +1218,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1249,20 +1246,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1280,20 +1277,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1311,20 +1308,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1336,20 +1333,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1364,20 +1361,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1454,20 +1451,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1507,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1566,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1597,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1619,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index 13441c362..62f8441bc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -811,20 +808,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -842,20 +839,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -923,17 +920,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1036,17 +1033,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1058,17 +1055,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1080,17 +1077,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1108,17 +1105,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1130,17 +1127,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1152,17 +1149,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1174,20 +1171,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1199,20 +1196,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1314,20 +1311,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1345,20 +1342,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1370,20 +1367,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1432,20 +1429,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1463,20 +1460,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1488,20 +1485,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1541,20 +1538,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1603,17 +1600,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1625,17 +1622,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index dabf629dd..c4872d266 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -811,20 +808,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -842,20 +839,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -923,17 +920,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1036,17 +1033,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1058,17 +1055,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1080,17 +1077,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1108,17 +1105,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1130,17 +1127,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1152,17 +1149,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1174,20 +1171,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1199,20 +1196,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1314,20 +1311,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1345,20 +1342,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1370,20 +1367,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1432,20 +1429,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1463,20 +1460,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1488,20 +1485,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1541,20 +1538,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1603,17 +1600,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1625,17 +1622,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index 714196152..31a81fb66 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -811,20 +808,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -842,20 +839,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -923,17 +920,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1036,17 +1033,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1058,17 +1055,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1080,17 +1077,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1108,17 +1105,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1130,17 +1127,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1152,17 +1149,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1174,20 +1171,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1199,20 +1196,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1314,20 +1311,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1345,20 +1342,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1370,20 +1367,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1432,20 +1429,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1463,20 +1460,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1488,20 +1485,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1541,20 +1538,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1603,17 +1600,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1625,17 +1622,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index 8e43b9e59..7c214e370 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -550,13 +550,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -571,20 +568,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -602,20 +599,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -627,20 +624,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -655,20 +652,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -683,17 +680,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -708,17 +705,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -730,17 +727,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -752,17 +749,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -774,17 +771,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -796,17 +793,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -818,17 +815,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -868,17 +865,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -890,17 +887,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -912,17 +909,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -934,20 +931,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -993,20 +990,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1018,20 +1015,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1052,20 +1049,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1077,20 +1074,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1105,20 +1102,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1136,7 +1133,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1181,6 +1181,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif index 15b954d5f..919eb0d23 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif @@ -784,13 +784,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -802,20 +799,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -830,20 +827,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -858,17 +855,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -883,17 +880,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -905,17 +902,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -927,17 +924,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -949,17 +946,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -971,17 +968,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -993,17 +990,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1015,17 +1012,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1043,17 +1040,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1065,17 +1062,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1087,17 +1084,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1109,20 +1106,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1140,17 +1137,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1165,20 +1162,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1193,20 +1190,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1280,20 +1277,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1308,20 +1305,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1342,20 +1339,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1373,20 +1370,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1454,20 +1451,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1482,20 +1479,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1507,20 +1504,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1532,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1566,17 +1563,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1597,17 +1594,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1619,17 +1616,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1641,7 +1638,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1666,6 +1666,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif index fab135633..9ab35211b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif @@ -548,13 +548,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -566,20 +563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -594,20 +591,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -625,20 +622,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -653,17 +650,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -678,17 +675,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -700,17 +697,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -722,17 +719,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -744,17 +741,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -766,17 +763,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -788,17 +785,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -810,17 +807,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -907,20 +904,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -938,20 +935,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -963,20 +960,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -997,20 +994,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1022,20 +1019,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1134,7 +1131,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1179,6 +1179,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif index cf6a8bc4d..970d913bd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif @@ -784,13 +784,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -802,20 +799,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -830,20 +827,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -858,17 +855,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -883,17 +880,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -905,17 +902,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -927,17 +924,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -949,17 +946,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -971,17 +968,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -993,17 +990,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1015,17 +1012,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1043,17 +1040,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1065,17 +1062,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1087,17 +1084,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1109,20 +1106,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1140,17 +1137,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1165,20 +1162,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1193,20 +1190,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1280,20 +1277,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1308,20 +1305,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1342,20 +1339,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1373,20 +1370,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1398,20 +1395,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1454,20 +1451,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1482,20 +1479,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1507,20 +1504,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1532,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1566,17 +1563,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1597,17 +1594,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1619,17 +1616,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1641,7 +1638,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1666,6 +1666,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif index 19fdf00ea..b06af7739 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif @@ -770,13 +770,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -788,20 +785,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -841,20 +838,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -872,20 +869,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -900,20 +897,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -928,20 +925,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -993,20 +990,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1018,20 +1015,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1049,20 +1046,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1136,17 +1133,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1158,17 +1155,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1180,17 +1177,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1205,17 +1202,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1252,17 +1249,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1274,17 +1271,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1318,17 +1315,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1340,17 +1337,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1362,17 +1359,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1490,20 +1487,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1515,20 +1512,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1644,6 +1644,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif index 66059aa34..1a0b2f52f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -812,20 +809,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -843,20 +840,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -924,17 +921,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -949,17 +946,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -971,17 +968,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -993,17 +990,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1015,17 +1012,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1037,17 +1034,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1059,17 +1056,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1081,17 +1078,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1109,17 +1106,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1131,17 +1128,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1153,17 +1150,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1175,20 +1172,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1200,20 +1197,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1231,17 +1228,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1256,20 +1253,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1284,20 +1281,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1315,20 +1312,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1346,20 +1343,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1371,20 +1368,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1399,20 +1396,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1433,20 +1430,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1464,20 +1461,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1489,20 +1486,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1514,20 +1511,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1542,20 +1539,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1604,17 +1601,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1626,17 +1623,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif index 9032c9d7f..59b669cea 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif @@ -770,13 +770,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -788,20 +785,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -841,20 +838,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -872,20 +869,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -900,20 +897,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -928,20 +925,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -993,20 +990,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1018,20 +1015,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1049,20 +1046,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1136,17 +1133,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1158,17 +1155,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1180,17 +1177,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1205,17 +1202,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1252,17 +1249,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1274,17 +1271,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1318,17 +1315,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1340,17 +1337,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1362,17 +1359,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1490,20 +1487,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1515,20 +1512,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1644,6 +1644,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif index d871a6de1..1fd5f10a1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -837,20 +834,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -893,17 +890,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -918,17 +915,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -940,17 +937,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -962,17 +959,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -984,17 +981,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1006,17 +1003,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1028,17 +1025,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1050,17 +1047,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1078,17 +1075,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1100,17 +1097,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1122,17 +1119,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1144,20 +1141,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1169,20 +1166,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1225,20 +1222,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1253,20 +1250,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1284,20 +1281,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1312,20 +1309,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1343,20 +1340,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1368,20 +1365,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1396,20 +1393,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1430,20 +1427,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1461,20 +1458,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1486,20 +1483,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1539,20 +1536,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1570,17 +1567,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1601,17 +1598,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1623,17 +1620,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif index a806bccd9..d337b9ff2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif @@ -547,13 +547,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -571,20 +568,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -596,20 +593,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -624,20 +621,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -652,17 +649,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -677,17 +674,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -699,17 +696,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -721,17 +718,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -743,17 +740,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -765,17 +762,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -787,17 +784,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -809,17 +806,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -837,17 +834,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -859,17 +856,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -881,17 +878,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -903,20 +900,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -931,20 +928,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -959,20 +956,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -990,20 +987,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1015,20 +1012,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1049,20 +1046,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1133,7 +1130,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1178,6 +1178,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index 054c162aa..740d26351 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -836,20 +833,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -892,17 +889,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -917,17 +914,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -939,17 +936,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -961,17 +958,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -983,17 +980,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1005,17 +1002,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1027,17 +1024,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1049,17 +1046,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1077,17 +1074,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1099,17 +1096,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1121,17 +1118,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1143,20 +1140,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1168,20 +1165,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1199,17 +1196,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1252,20 +1249,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1311,20 +1308,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1342,20 +1339,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1367,20 +1364,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1395,20 +1392,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1507,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1566,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1597,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1619,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index d1c5f94b6..a312bbe48 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -792,20 +789,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -817,20 +814,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -845,20 +842,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -873,17 +870,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -898,17 +895,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -920,17 +917,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -942,17 +939,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -964,17 +961,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -986,17 +983,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1008,17 +1005,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1030,17 +1027,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1058,17 +1055,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1080,17 +1077,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1102,17 +1099,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1149,20 +1146,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1180,17 +1177,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1205,20 +1202,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1233,20 +1230,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1264,20 +1261,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1292,20 +1289,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1323,20 +1320,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1348,20 +1345,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1376,20 +1373,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1410,20 +1407,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1441,20 +1438,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1466,20 +1463,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1491,20 +1488,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1519,20 +1516,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1603,17 +1600,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1625,7 +1622,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1650,6 +1650,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index 6e7945105..e0b79a3a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -836,20 +833,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -892,17 +889,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -917,17 +914,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -939,17 +936,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -961,17 +958,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -983,17 +980,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1005,17 +1002,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1027,17 +1024,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1049,17 +1046,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1077,17 +1074,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1099,17 +1096,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1121,17 +1118,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1143,20 +1140,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1168,20 +1165,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1199,17 +1196,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1252,20 +1249,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1311,20 +1308,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1342,20 +1339,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1367,20 +1364,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1395,20 +1392,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1429,20 +1426,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1460,20 +1457,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1485,20 +1482,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1507,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1566,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1597,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1619,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index 8a4f25a9b..889776c6f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -547,13 +547,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -571,20 +568,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -596,20 +593,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -624,20 +621,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -652,17 +649,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -677,17 +674,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -699,17 +696,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -721,17 +718,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -743,17 +740,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -765,17 +762,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -787,17 +784,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -809,17 +806,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -837,17 +834,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -859,17 +856,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -881,17 +878,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -903,20 +900,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -931,20 +928,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -959,20 +956,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -990,20 +987,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1015,20 +1012,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1049,20 +1046,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1133,7 +1130,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1178,6 +1178,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif index 30520d43a..f3aa1ef58 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -832,20 +829,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -885,17 +882,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -907,17 +904,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -929,17 +926,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -951,17 +948,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -973,17 +970,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -995,17 +992,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1017,17 +1014,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1045,17 +1042,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1067,17 +1064,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1089,17 +1086,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1111,20 +1108,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1136,20 +1133,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1167,17 +1164,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1192,20 +1189,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1220,20 +1217,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1251,20 +1248,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1279,20 +1276,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1310,20 +1307,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1335,20 +1332,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1363,20 +1360,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1397,20 +1394,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1428,20 +1425,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1453,20 +1450,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1484,20 +1481,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1506,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1565,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1596,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1618,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif index 9935e605a..70b6b30a1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif @@ -761,13 +761,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -779,20 +776,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -835,17 +832,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -904,17 +901,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -926,17 +923,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1020,17 +1017,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1042,17 +1039,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1064,17 +1061,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1086,20 +1083,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1111,20 +1108,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1142,17 +1139,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1167,20 +1164,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1195,20 +1192,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1226,20 +1223,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1254,20 +1251,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1285,20 +1282,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1310,20 +1307,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1338,20 +1335,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1372,20 +1369,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1403,20 +1400,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1428,20 +1425,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1484,20 +1481,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1509,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1543,17 +1540,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1574,17 +1571,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1596,17 +1593,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1618,7 +1615,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1643,6 +1643,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif index 95879d033..c60f2fb69 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif @@ -783,13 +783,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -801,20 +798,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +854,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -904,17 +901,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -926,17 +923,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1042,17 +1039,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1064,17 +1061,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1086,17 +1083,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1108,20 +1105,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1133,20 +1130,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1189,20 +1186,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1217,20 +1214,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1248,20 +1245,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1276,20 +1273,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1307,20 +1304,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1332,20 +1329,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1360,20 +1357,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1394,20 +1391,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1425,20 +1422,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1450,20 +1447,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1481,20 +1478,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1503,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1531,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1562,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1593,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1615,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,7 +1637,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1665,6 +1665,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif index ccb761236..d2eb7b22d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif @@ -783,13 +783,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -801,20 +798,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +854,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -904,17 +901,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -926,17 +923,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1042,17 +1039,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1064,17 +1061,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1086,17 +1083,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1108,20 +1105,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1133,20 +1130,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1189,20 +1186,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1217,20 +1214,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1248,20 +1245,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1276,20 +1273,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1307,20 +1304,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1332,20 +1329,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1360,20 +1357,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1394,20 +1391,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1425,20 +1422,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1450,20 +1447,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1481,20 +1478,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1503,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1531,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1562,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1593,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1615,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,7 +1637,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1665,6 +1665,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif index 66eed0aa6..fbe4213d4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif @@ -789,13 +789,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -835,20 +832,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -894,17 +891,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -919,17 +916,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -941,17 +938,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -963,17 +960,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -985,17 +982,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1007,17 +1004,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1029,17 +1026,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1051,17 +1048,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1079,17 +1076,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1101,17 +1098,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1123,17 +1120,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1145,20 +1142,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1176,17 +1173,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1201,20 +1198,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1229,20 +1226,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1260,20 +1257,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1291,20 +1288,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1316,20 +1313,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1344,20 +1341,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1378,20 +1375,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1409,20 +1406,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1434,20 +1431,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1487,20 +1484,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1509,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1602,17 +1599,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1624,17 +1621,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1646,7 +1643,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1671,6 +1671,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif index 42bb4375c..9c26e0574 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif @@ -789,13 +789,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -835,20 +832,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -894,17 +891,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -919,17 +916,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -941,17 +938,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -963,17 +960,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -985,17 +982,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1007,17 +1004,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1029,17 +1026,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1051,17 +1048,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1079,17 +1076,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1101,17 +1098,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1123,17 +1120,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1145,20 +1142,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1176,17 +1173,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1201,20 +1198,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1229,20 +1226,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1260,20 +1257,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1291,20 +1288,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1316,20 +1313,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1344,20 +1341,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1378,20 +1375,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1409,20 +1406,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1434,20 +1431,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1487,20 +1484,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1509,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1602,17 +1599,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1624,17 +1621,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1646,7 +1643,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1671,6 +1671,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif index 929259100..c795810c2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif @@ -548,13 +548,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -566,20 +563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -594,20 +591,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -625,20 +622,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -653,17 +650,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -678,17 +675,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -700,17 +697,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -722,17 +719,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -744,17 +741,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -766,17 +763,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -788,17 +785,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -810,17 +807,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -907,20 +904,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -938,20 +935,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -963,20 +960,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -997,20 +994,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1022,20 +1019,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1134,7 +1131,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1179,6 +1179,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif index b29612c1f..819864167 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif @@ -793,13 +793,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -836,20 +833,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -923,20 +920,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +948,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1013,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1038,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1097,20 +1094,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1159,17 +1156,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1181,17 +1178,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1203,17 +1200,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1228,17 +1225,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1253,17 +1250,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1275,17 +1272,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1319,17 +1316,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1341,17 +1338,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1363,17 +1360,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1385,17 +1382,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1485,17 +1482,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1510,20 +1507,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1541,20 +1538,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1591,20 +1588,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1619,20 +1616,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1650,7 +1647,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1675,6 +1675,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif index 29983f715..ed35008ef 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif @@ -785,13 +785,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +800,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -862,17 +859,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -887,17 +884,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -909,17 +906,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -931,17 +928,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -953,17 +950,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -975,17 +972,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -997,17 +994,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1019,17 +1016,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1047,17 +1044,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1069,17 +1066,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1091,17 +1088,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1113,20 +1110,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1144,17 +1141,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1169,20 +1166,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1197,20 +1194,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1228,20 +1225,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1256,20 +1253,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1287,20 +1284,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1312,20 +1309,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1340,20 +1337,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1374,20 +1371,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1405,20 +1402,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1430,20 +1427,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1455,20 +1452,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1483,20 +1480,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1567,17 +1564,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1598,17 +1595,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1620,17 +1617,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1642,7 +1639,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1667,6 +1667,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif index 13aff9024..2655b2e5d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif @@ -770,13 +770,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -788,20 +785,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -813,20 +810,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -841,20 +838,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -872,20 +869,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -900,20 +897,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -928,20 +925,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -993,20 +990,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1018,20 +1015,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1049,20 +1046,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1136,17 +1133,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1158,17 +1155,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1180,17 +1177,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1205,17 +1202,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1230,17 +1227,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1252,17 +1249,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1274,17 +1271,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1318,17 +1315,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1340,17 +1337,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1362,17 +1359,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1459,20 +1456,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1490,20 +1487,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1515,20 +1512,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1540,20 +1537,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1568,20 +1565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1644,6 +1644,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif index f4d840892..2cb1a3d62 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -835,20 +832,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -863,17 +860,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -888,17 +885,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -910,17 +907,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -932,17 +929,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -954,17 +951,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -976,17 +973,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -998,17 +995,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1020,17 +1017,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1048,17 +1045,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1070,17 +1067,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1092,17 +1089,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1114,20 +1111,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1145,17 +1142,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1170,20 +1167,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1198,20 +1195,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1229,20 +1226,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1257,20 +1254,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1288,20 +1285,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1313,20 +1310,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1341,20 +1338,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1375,20 +1372,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1406,20 +1403,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1431,20 +1428,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1456,20 +1453,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1484,20 +1481,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1506,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1565,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1596,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1618,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif index ad6747277..671bb1a69 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -835,20 +832,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -863,17 +860,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -888,17 +885,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -910,17 +907,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -932,17 +929,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -954,17 +951,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -976,17 +973,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -998,17 +995,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1020,17 +1017,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1048,17 +1045,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1070,17 +1067,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1092,17 +1089,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1114,20 +1111,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1145,17 +1142,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1170,20 +1167,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1198,20 +1195,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1229,20 +1226,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1257,20 +1254,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1288,20 +1285,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1313,20 +1310,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1341,20 +1338,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1375,20 +1372,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1406,20 +1403,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1431,20 +1428,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1456,20 +1453,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1484,20 +1481,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1506,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1534,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1565,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1596,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1618,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif index 7f9ace01e..21276b14c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif @@ -546,13 +546,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -564,20 +561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -595,20 +592,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -623,17 +620,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -648,17 +645,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -670,17 +667,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -692,17 +689,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -714,17 +711,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -736,17 +733,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -758,17 +755,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -780,17 +777,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -808,17 +805,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -830,17 +827,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -852,17 +849,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -877,20 +874,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -905,20 +902,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -936,20 +933,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -961,20 +958,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -995,20 +992,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1020,20 +1017,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1048,20 +1045,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1132,7 +1129,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1177,6 +1177,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif index 815688fa4..63cff34d6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif @@ -785,13 +785,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +800,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -862,17 +859,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -887,17 +884,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -909,17 +906,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -931,17 +928,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -953,17 +950,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -975,17 +972,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -997,17 +994,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1019,17 +1016,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1047,17 +1044,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1069,17 +1066,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1091,17 +1088,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1113,20 +1110,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1144,17 +1141,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1169,20 +1166,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1197,20 +1194,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1228,20 +1225,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1256,20 +1253,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1287,20 +1284,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1312,20 +1309,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1340,20 +1337,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1374,20 +1371,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1405,20 +1402,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1430,20 +1427,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1455,20 +1452,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1483,20 +1480,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1567,17 +1564,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1598,17 +1595,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1620,17 +1617,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1642,7 +1639,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1667,6 +1667,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif index 4feb22244..848b1e3b0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif @@ -796,13 +796,10 @@ "rules": [ { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -820,20 +817,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -845,20 +842,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -873,20 +870,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -907,17 +904,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -929,17 +926,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -951,17 +948,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -976,17 +973,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1001,17 +998,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1023,17 +1020,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1045,17 +1042,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1067,17 +1064,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1089,17 +1086,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1111,17 +1108,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1133,17 +1130,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1161,17 +1158,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1183,17 +1180,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1205,17 +1202,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1227,20 +1224,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1252,20 +1249,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1283,17 +1280,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1308,20 +1305,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1336,20 +1333,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1367,20 +1364,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1395,20 +1392,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1426,20 +1423,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1451,20 +1448,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1479,20 +1476,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1513,20 +1510,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1544,20 +1541,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1569,20 +1566,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1594,20 +1591,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1622,20 +1619,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1653,7 +1650,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1678,6 +1678,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif index a5b456f82..8df82d0c4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif @@ -624,13 +624,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -642,20 +639,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -670,20 +667,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -698,20 +695,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -732,20 +729,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -763,20 +760,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -788,20 +785,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -819,20 +816,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -847,20 +844,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -875,17 +872,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -900,17 +897,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -922,17 +919,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -944,17 +941,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -966,17 +963,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -988,17 +985,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1010,17 +1007,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1032,17 +1029,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1060,17 +1057,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1082,17 +1079,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1104,17 +1101,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,7 +1291,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1339,6 +1339,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif index d356d8b5b..80e240961 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif @@ -550,13 +550,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -568,20 +565,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -596,20 +593,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -627,20 +624,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -655,20 +652,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -683,17 +680,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -708,17 +705,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -730,17 +727,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -752,17 +749,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -774,17 +771,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -796,17 +793,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -818,17 +815,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -868,17 +865,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -890,17 +887,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -912,17 +909,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -937,20 +934,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -968,20 +965,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -993,20 +990,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1027,20 +1024,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1052,20 +1049,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1077,20 +1074,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1105,20 +1102,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1136,7 +1133,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1181,6 +1181,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif index 317a07eaa..2657e9c08 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -833,20 +830,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -861,20 +858,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -920,20 +917,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -945,20 +942,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -973,20 +970,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1063,20 +1060,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1094,20 +1091,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1122,20 +1119,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1156,17 +1153,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1178,17 +1175,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1200,17 +1197,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1225,17 +1222,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1250,17 +1247,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1272,17 +1269,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1316,17 +1313,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1338,17 +1335,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1360,17 +1357,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1382,17 +1379,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1410,17 +1407,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1429,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1451,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1507,20 +1504,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1538,20 +1535,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1563,20 +1560,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1588,20 +1585,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1616,20 +1613,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif index b2a40a893..7b49280a7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +856,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +915,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +940,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +968,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1089,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1123,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1145,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1167,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1192,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1217,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1239,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1261,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1283,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1327,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1349,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1377,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1399,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1421,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1449,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1474,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif index dc600b2a0..952b46338 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif @@ -624,13 +624,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -645,20 +642,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -673,20 +670,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -707,20 +704,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -738,20 +735,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -763,20 +760,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -794,20 +791,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -819,20 +816,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -847,20 +844,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -875,17 +872,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -900,17 +897,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -922,17 +919,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -944,17 +941,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -966,17 +963,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -988,17 +985,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1010,17 +1007,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1032,17 +1029,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1060,17 +1057,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1082,17 +1079,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1104,17 +1101,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1154,20 +1151,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,7 +1291,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1339,6 +1339,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif index a204b13bc..69ddf6274 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif @@ -548,13 +548,10 @@ "rules": [ { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -569,20 +566,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -594,20 +591,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -622,20 +619,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -650,17 +647,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -675,17 +672,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -697,17 +694,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -719,17 +716,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -741,17 +738,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -763,17 +760,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -785,17 +782,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -807,17 +804,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -835,17 +832,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +854,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -879,17 +876,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -901,20 +898,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -929,20 +926,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -960,20 +957,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1019,20 +1016,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1134,7 +1131,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1179,6 +1179,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif index 0278ded2f..ed2e8e1e3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif @@ -794,13 +794,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -843,20 +840,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -877,17 +874,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -899,17 +896,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -921,17 +918,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -946,17 +943,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -971,17 +968,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -993,17 +990,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1015,17 +1012,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1037,17 +1034,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1059,17 +1056,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1081,17 +1078,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1103,17 +1100,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1131,17 +1128,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1153,17 +1150,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1197,20 +1194,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1228,17 +1225,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1253,20 +1250,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1281,20 +1278,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1312,20 +1309,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1340,20 +1337,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1371,20 +1368,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1396,20 +1393,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1424,20 +1421,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1458,20 +1455,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1489,20 +1486,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1514,20 +1511,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1539,20 +1536,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1567,20 +1564,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1592,20 +1589,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1620,20 +1617,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1651,7 +1648,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1676,6 +1676,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif index 50a1ecc3e..a8fb7089c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif @@ -794,13 +794,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -840,20 +837,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -874,17 +871,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -896,17 +893,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -918,17 +915,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -943,17 +940,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -968,17 +965,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -990,17 +987,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1012,17 +1009,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1034,17 +1031,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1056,17 +1053,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1078,17 +1075,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1100,17 +1097,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1128,17 +1125,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1150,17 +1147,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1172,17 +1169,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1194,20 +1191,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1219,20 +1216,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1250,17 +1247,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1275,20 +1272,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1303,20 +1300,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1334,20 +1331,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1362,20 +1359,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1393,20 +1390,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1418,20 +1415,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1446,20 +1443,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1480,20 +1477,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1511,20 +1508,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1536,20 +1533,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1567,20 +1564,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1592,20 +1589,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1620,20 +1617,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1651,7 +1648,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1676,6 +1676,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif index b8fbf1d45..36a857b6b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif @@ -622,13 +622,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -640,20 +637,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -668,20 +665,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -696,20 +693,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -730,20 +727,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -761,20 +758,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -817,20 +814,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -845,17 +842,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -870,17 +867,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -892,17 +889,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -914,17 +911,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -936,17 +933,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -958,17 +955,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -980,17 +977,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1002,17 +999,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1030,17 +1027,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1052,17 +1049,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1074,17 +1071,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1130,20 +1127,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1155,20 +1152,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1177,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1205,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1230,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1258,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,7 +1289,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1337,6 +1337,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif index 48497a80d..9c85f2193 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif @@ -548,13 +548,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -566,20 +563,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -594,20 +591,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -625,20 +622,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -653,17 +650,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -678,17 +675,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -700,17 +697,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -722,17 +719,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -744,17 +741,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -766,17 +763,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -788,17 +785,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -810,17 +807,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -907,20 +904,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -938,20 +935,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -963,20 +960,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -997,20 +994,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1022,20 +1019,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1075,20 +1072,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1134,7 +1131,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1179,6 +1179,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif index fa8670fd6..f78ae0aa5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif @@ -794,13 +794,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -843,20 +840,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -877,17 +874,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -899,17 +896,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -921,17 +918,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -946,17 +943,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -971,17 +968,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -993,17 +990,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1015,17 +1012,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1037,17 +1034,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1059,17 +1056,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1081,17 +1078,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1103,17 +1100,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1131,17 +1128,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1153,17 +1150,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1175,17 +1172,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1197,20 +1194,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1228,17 +1225,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1253,20 +1250,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1281,20 +1278,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1312,20 +1309,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1340,20 +1337,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1371,20 +1368,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1396,20 +1393,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1424,20 +1421,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1458,20 +1455,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1489,20 +1486,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1514,20 +1511,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1539,20 +1536,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1567,20 +1564,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1592,20 +1589,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1620,20 +1617,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1651,7 +1648,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1676,6 +1676,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif index 38aaad5c5..53a852bdd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif @@ -788,13 +788,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +828,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -862,17 +859,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -887,20 +884,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -918,20 +915,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -946,20 +943,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -974,20 +971,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1030,20 +1027,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1095,17 +1092,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1117,17 +1114,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1139,17 +1136,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1189,17 +1186,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1211,17 +1208,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1233,17 +1230,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1255,17 +1252,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1277,17 +1274,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1299,17 +1296,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1321,17 +1318,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1418,20 +1415,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1449,20 +1446,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1474,20 +1471,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1508,20 +1505,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1530,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1558,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1583,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1611,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,7 +1642,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1670,6 +1670,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif index bbdc49129..1efe8af75 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif index 7b2f7e84b..4dace2bce 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif @@ -790,13 +790,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -833,20 +830,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -864,17 +861,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -889,20 +886,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -917,20 +914,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -948,20 +945,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -976,20 +973,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1032,20 +1029,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1060,20 +1057,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1094,20 +1091,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1150,20 +1147,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1206,20 +1203,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1256,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1287,20 +1284,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1318,17 +1315,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1437,17 +1434,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1509,17 +1506,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1534,17 +1531,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1603,17 +1600,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1625,17 +1622,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1647,7 +1644,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1672,6 +1672,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif index 0e544ef02..2106596f9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1438,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1460,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1482,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1507,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1532,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1554,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1576,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif index 006f5ebd4..9ad06775e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif @@ -767,13 +767,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -785,20 +782,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -810,20 +807,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -841,17 +838,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -894,20 +891,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -925,20 +922,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -953,20 +950,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -984,20 +981,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1009,20 +1006,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1037,20 +1034,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1071,20 +1068,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1127,20 +1124,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1158,20 +1155,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1183,20 +1180,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1211,20 +1208,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1236,20 +1233,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1264,20 +1261,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1295,17 +1292,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1326,17 +1323,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1348,17 +1345,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1370,17 +1367,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1392,17 +1389,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1414,17 +1411,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1442,17 +1439,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1464,17 +1461,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1486,17 +1483,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1511,17 +1508,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1536,17 +1533,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1558,17 +1555,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1580,17 +1577,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1602,7 +1599,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1627,6 +1627,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif index 2f71a5cf8..f97b4d9b7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif @@ -769,13 +769,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +784,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -843,17 +840,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -955,20 +952,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -986,20 +983,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1011,20 +1008,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1104,20 +1101,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1213,20 +1210,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1238,20 +1235,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1266,20 +1263,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1328,17 +1325,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1444,17 +1441,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1466,17 +1463,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1488,17 +1485,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1513,17 +1510,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1538,17 +1535,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1560,17 +1557,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1582,17 +1579,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1604,7 +1601,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1629,6 +1629,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif index 43b92a5a0..3932661a6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif index ed0c44d0c..8cd3417e8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif index e43b55a5d..2bf4e51a2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif index 46fb26cc1..fed7f4958 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif @@ -769,13 +769,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +784,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -843,17 +840,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -955,20 +952,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -986,20 +983,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1011,20 +1008,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1104,20 +1101,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1213,20 +1210,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1238,20 +1235,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1266,20 +1263,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1328,17 +1325,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1444,17 +1441,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1466,17 +1463,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1488,17 +1485,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1513,17 +1510,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1538,17 +1535,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1560,17 +1557,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1582,17 +1579,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1604,7 +1601,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1629,6 +1629,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif index 02ef550bd..ad3165422 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif index 0a41131de..eb72b4850 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif @@ -780,13 +780,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -798,20 +795,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -823,20 +820,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -854,17 +851,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -879,20 +876,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -907,20 +904,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -938,20 +935,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -966,20 +963,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -997,20 +994,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1022,20 +1019,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1084,20 +1081,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1115,20 +1112,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1140,20 +1137,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1171,20 +1168,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1196,20 +1193,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1249,20 +1246,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1277,20 +1274,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1339,17 +1336,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1361,17 +1358,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1408,17 +1405,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1477,17 +1474,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1499,17 +1496,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1521,17 +1518,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1543,17 +1540,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1593,17 +1590,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1615,7 +1612,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } } ], "properties": { @@ -1640,6 +1640,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif index 0b2801743..62c28fec1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif @@ -769,13 +769,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +784,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -843,17 +840,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -955,20 +952,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -986,20 +983,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1011,20 +1008,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1104,20 +1101,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1213,20 +1210,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1238,20 +1235,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1266,20 +1263,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1328,17 +1325,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1444,17 +1441,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1466,17 +1463,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1488,17 +1485,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1513,17 +1510,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1538,17 +1535,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1560,17 +1557,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1582,17 +1579,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1604,7 +1601,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1629,6 +1629,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif index 68c182933..d8cf9c904 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif index 7147c90cf..00a2a57b7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif @@ -767,13 +767,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -785,20 +782,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -810,20 +807,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -841,17 +838,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -866,20 +863,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -894,20 +891,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -925,20 +922,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -953,20 +950,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -984,20 +981,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1009,20 +1006,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1037,20 +1034,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1071,20 +1068,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1102,20 +1099,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1127,20 +1124,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1158,20 +1155,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1183,20 +1180,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1211,20 +1208,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1236,20 +1233,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1264,20 +1261,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1295,17 +1292,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1326,17 +1323,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1348,17 +1345,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1370,17 +1367,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1392,17 +1389,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1414,17 +1411,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1442,17 +1439,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1464,17 +1461,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1486,17 +1483,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1511,17 +1508,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1536,17 +1533,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1558,17 +1555,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1580,17 +1577,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1602,7 +1599,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1627,6 +1627,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif index c48dcf63a..55e6791e6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif @@ -769,13 +769,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +784,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -843,17 +840,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -955,20 +952,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -986,20 +983,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1011,20 +1008,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1104,20 +1101,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1213,20 +1210,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1238,20 +1235,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1266,20 +1263,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1328,17 +1325,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1444,17 +1441,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1466,17 +1463,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1488,17 +1485,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1513,17 +1510,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1538,17 +1535,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1560,17 +1557,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1582,17 +1579,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1604,7 +1601,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1629,6 +1629,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif index ef272b59e..f89139875 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif @@ -50,6 +50,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif index 4a5305958..578b66b28 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1443,17 +1440,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1465,17 +1462,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1487,17 +1484,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1512,17 +1509,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1537,17 +1534,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1559,17 +1556,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1581,17 +1578,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif index 2dc9dc91b..6e851b19b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif @@ -769,13 +769,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +784,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +809,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -843,17 +840,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -868,20 +865,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -896,20 +893,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -927,20 +924,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -955,20 +952,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -986,20 +983,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1011,20 +1008,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1039,20 +1036,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1104,20 +1101,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1129,20 +1126,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1160,20 +1157,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1185,20 +1182,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1213,20 +1210,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1238,20 +1235,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1266,20 +1263,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1297,17 +1294,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1328,17 +1325,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1444,17 +1441,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1466,17 +1463,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1488,17 +1485,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1513,17 +1510,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1538,17 +1535,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1560,17 +1557,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1582,17 +1579,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1604,7 +1601,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } } ], "properties": { @@ -1629,6 +1629,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif index aa7b2be06..5b0b10f0a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif @@ -428,13 +428,13 @@ { "ruleId": "BA2006", "ruleIndex": 17, - "level": "error", + "kind": "pass", + "level": "none", "message": { - "id": "Error", + "id": "Pass", "arguments": [ "clangcl.pe.cpp.codeview.exe", - "", - "clang version 13.0.0 : cxx : 13000.0.0.0 : [directly linked] (hello-d24821.obj)\r\n" + "Microsoft (R) Optimizing Compiler:C:19.26.28900.8, Microsoft (R) Optimizing Compiler:C:19.29.30034.2, Microsoft (R) Optimizing Compiler:Cxx:19.26.28900.8, Microsoft (R) Optimizing Compiler:Cxx:19.29.30034.2" ] }, "locations": [ @@ -783,13 +783,10 @@ "rules": [ { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -801,20 +798,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +854,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -882,17 +879,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -904,17 +901,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -926,17 +923,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -948,17 +945,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -970,17 +967,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -992,17 +989,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1014,17 +1011,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1042,17 +1039,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1064,17 +1061,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1086,17 +1083,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1108,20 +1105,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1133,20 +1130,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1164,17 +1161,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1189,20 +1186,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1217,20 +1214,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1248,20 +1245,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1276,20 +1273,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1307,20 +1304,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1332,20 +1329,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1360,20 +1357,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1394,20 +1391,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1425,20 +1422,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1450,20 +1447,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1481,20 +1478,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1503,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1531,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1562,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1593,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1615,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,7 +1637,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } } ], "properties": { @@ -1665,6 +1665,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif index ce00f81c7..1d40f5b78 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif index 21efb5993..e9da98295 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -885,20 +882,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -913,20 +910,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -944,20 +941,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -972,20 +969,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1003,20 +1000,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1028,20 +1025,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1056,20 +1053,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1090,20 +1087,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1121,20 +1118,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1146,20 +1143,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1177,20 +1174,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1202,20 +1199,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1230,20 +1227,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1314,17 +1311,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1458,17 +1455,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1483,17 +1480,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1593,17 +1590,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1615,17 +1612,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif index 4505ff73a..a1e549e32 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif @@ -763,13 +763,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +778,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +803,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +834,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +859,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +918,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +946,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +977,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1002,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1030,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1064,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1095,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1120,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1151,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1176,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1204,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1229,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1257,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1288,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1319,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1341,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1363,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1385,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1407,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1429,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1451,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1476,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1501,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1523,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1545,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1567,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,7 +1595,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1623,6 +1623,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif index dc34fe47e..ab9c258f9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif @@ -764,13 +764,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -782,20 +779,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -863,20 +860,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -891,20 +888,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -922,20 +919,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -950,20 +947,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -981,20 +978,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1006,20 +1003,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1034,20 +1031,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1155,20 +1152,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1177,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1205,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1230,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1258,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,17 +1289,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1323,17 +1320,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1480,17 +1477,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1624,6 +1624,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif index f960deb6c..81fd266b3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif index 2cde19251..3ff12dfa9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif @@ -804,13 +804,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -822,20 +819,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -847,20 +844,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -878,17 +875,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -903,20 +900,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -931,20 +928,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -990,20 +987,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1021,20 +1018,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1046,20 +1043,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1108,20 +1105,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1139,20 +1136,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1164,20 +1161,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1195,20 +1192,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1220,20 +1217,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1248,20 +1245,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1273,20 +1270,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1301,20 +1298,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1363,17 +1360,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1385,17 +1382,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1407,17 +1404,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1429,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1479,17 +1476,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1501,17 +1498,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1523,17 +1520,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1545,17 +1542,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1567,17 +1564,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1589,17 +1586,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1617,17 +1614,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1639,17 +1636,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1661,7 +1658,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } } ], "properties": { @@ -1686,6 +1686,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif index 8d9950746..11b0ddfd4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif @@ -791,13 +791,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -834,20 +831,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -865,17 +862,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -890,20 +887,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -918,20 +915,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -949,20 +946,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -977,20 +974,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1033,20 +1030,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1061,20 +1058,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1095,20 +1092,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1151,20 +1148,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1207,20 +1204,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1257,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1288,20 +1285,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1319,17 +1316,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1350,17 +1347,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1372,17 +1369,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1394,17 +1391,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1416,17 +1413,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1438,17 +1435,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1460,17 +1457,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1532,17 +1529,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1554,17 +1551,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1576,17 +1573,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1598,17 +1595,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1620,17 +1617,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1648,7 +1645,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1673,6 +1673,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif index 9ae289069..936dfd938 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -885,20 +882,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -913,20 +910,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -944,20 +941,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -972,20 +969,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1003,20 +1000,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1028,20 +1025,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1056,20 +1053,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1090,20 +1087,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1121,20 +1118,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1146,20 +1143,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1177,20 +1174,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1202,20 +1199,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1230,20 +1227,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1314,17 +1311,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1458,17 +1455,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1483,17 +1480,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1593,17 +1590,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1615,17 +1612,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif index 9d57a1972..18a6fcf49 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +802,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +827,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -861,17 +858,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -886,20 +883,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -914,20 +911,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -945,20 +942,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -973,20 +970,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1004,20 +1001,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1029,20 +1026,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1057,20 +1054,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1091,20 +1088,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1122,20 +1119,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1147,20 +1144,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1178,20 +1175,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1203,20 +1200,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1231,20 +1228,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1256,20 +1253,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1284,20 +1281,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1315,17 +1312,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1456,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1594,17 +1591,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1616,17 +1613,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif index 9fdc9593e..c5fff30d4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif @@ -785,13 +785,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +800,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +825,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -859,17 +856,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -884,20 +881,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -912,20 +909,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -943,20 +940,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -971,20 +968,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1002,20 +999,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1027,20 +1024,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1055,20 +1052,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1089,20 +1086,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1120,20 +1117,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1145,20 +1142,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1176,20 +1173,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1201,20 +1198,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1229,20 +1226,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1254,20 +1251,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1282,20 +1279,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1313,17 +1310,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1344,17 +1341,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1366,17 +1363,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1388,17 +1385,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1410,17 +1407,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1432,17 +1429,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1504,17 +1501,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1526,17 +1523,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1548,17 +1545,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1570,17 +1567,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1592,17 +1589,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1614,17 +1611,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1642,7 +1639,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1667,6 +1667,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif index cf64d599b..8513c526d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif @@ -768,13 +768,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +783,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +808,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -842,17 +839,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -867,20 +864,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -895,20 +892,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -926,20 +923,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -954,20 +951,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -985,20 +982,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1010,20 +1007,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1038,20 +1035,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1072,20 +1069,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1103,20 +1100,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1128,20 +1125,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1159,20 +1156,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1184,20 +1181,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1212,20 +1209,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1237,20 +1234,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1265,20 +1262,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1296,17 +1293,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1327,17 +1324,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1349,17 +1346,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1371,17 +1368,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1393,17 +1390,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1415,17 +1412,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1437,17 +1434,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1459,17 +1456,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1509,17 +1506,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1531,17 +1528,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1553,17 +1550,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1575,17 +1572,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1603,7 +1600,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1628,6 +1628,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif index f5b8ac7a4..2592d3ea2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +802,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +827,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -861,17 +858,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -886,20 +883,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -914,20 +911,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -945,20 +942,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -973,20 +970,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1004,20 +1001,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1029,20 +1026,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1057,20 +1054,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1091,20 +1088,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1122,20 +1119,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1147,20 +1144,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1178,20 +1175,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1203,20 +1200,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1231,20 +1228,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1256,20 +1253,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1284,20 +1281,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1315,17 +1312,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1456,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1594,17 +1591,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1616,17 +1613,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif index a0c7aa7f8..1b13fc73c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif index 35217331f..aed6007fa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif index 4ab87a2ac..d06cc2060 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif index 4dcda324a..572620b5d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif index e6498d366..18041a37d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif index 47a394dca..a77beb456 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif index 38e30ada3..2f262ac72 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif index dc36e1ebe..f85e732f4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif @@ -804,13 +804,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -822,20 +819,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -847,20 +844,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -878,17 +875,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -903,20 +900,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -931,20 +928,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -962,20 +959,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -990,20 +987,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1021,20 +1018,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1046,20 +1043,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1074,20 +1071,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1108,20 +1105,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1139,20 +1136,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1164,20 +1161,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1195,20 +1192,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1220,20 +1217,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1248,20 +1245,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1273,20 +1270,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1301,20 +1298,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1332,17 +1329,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1363,17 +1360,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1385,17 +1382,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1407,17 +1404,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1429,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1479,17 +1476,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1501,17 +1498,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1523,17 +1520,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1545,17 +1542,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1567,17 +1564,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1589,17 +1586,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1617,17 +1614,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1639,17 +1636,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1661,7 +1658,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } } ], "properties": { @@ -1686,6 +1686,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif index f5692be5b..ad4101d3d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif @@ -764,13 +764,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -782,20 +779,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -863,20 +860,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -891,20 +888,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -922,20 +919,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -950,20 +947,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -981,20 +978,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1006,20 +1003,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1034,20 +1031,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1155,20 +1152,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1177,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1205,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1230,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1258,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,17 +1289,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1323,17 +1320,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1436,17 +1433,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1461,17 +1458,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1483,17 +1480,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1624,6 +1624,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif index 2b889b4af..283ccc4c2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif @@ -780,13 +780,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -798,20 +795,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -823,20 +820,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -854,17 +851,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -879,20 +876,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -907,20 +904,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -938,20 +935,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -966,20 +963,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -997,20 +994,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1022,20 +1019,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1050,20 +1047,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1084,20 +1081,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1115,20 +1112,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1140,20 +1137,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1171,20 +1168,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1196,20 +1193,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1224,20 +1221,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1249,20 +1246,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1277,20 +1274,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1308,17 +1305,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1339,17 +1336,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1361,17 +1358,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1383,17 +1380,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1408,17 +1405,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1477,17 +1474,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1499,17 +1496,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1521,17 +1518,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1543,17 +1540,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1593,17 +1590,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1615,7 +1612,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } } ], "properties": { @@ -1640,6 +1640,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif index de066311b..336295499 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif @@ -546,13 +546,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -564,20 +561,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -592,20 +589,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -623,20 +620,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -651,17 +648,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -676,17 +673,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -698,17 +695,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -720,17 +717,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -742,17 +739,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -764,17 +761,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -786,17 +783,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -808,17 +805,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -836,17 +833,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -858,17 +855,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -880,17 +877,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -905,20 +902,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -936,20 +933,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -961,20 +958,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -995,20 +992,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1020,20 +1017,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1048,20 +1045,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1073,20 +1070,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1132,7 +1129,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } } ], "properties": { @@ -1177,6 +1177,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif index 7a31b65dd..2262b817b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif index 129304a9e..f1c44447a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif index 71ffc0b1e..5fbb05e12 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif @@ -764,13 +764,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -782,20 +779,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -807,20 +804,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -838,17 +835,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -863,20 +860,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -891,20 +888,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -922,20 +919,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -950,20 +947,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -981,20 +978,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1006,20 +1003,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1034,20 +1031,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1068,20 +1065,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1099,20 +1096,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1124,20 +1121,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1155,20 +1152,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1177,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1205,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1230,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1258,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,17 +1289,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1323,17 +1320,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1455,17 +1452,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1480,17 +1477,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1599,7 +1596,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1624,6 +1624,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif index 50d43532d..312145eac 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif @@ -786,13 +786,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +801,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -829,20 +826,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -860,17 +857,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -885,20 +882,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -913,20 +910,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -944,20 +941,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -972,20 +969,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1003,20 +1000,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1028,20 +1025,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1056,20 +1053,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1090,20 +1087,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1121,20 +1118,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1146,20 +1143,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1177,20 +1174,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1202,20 +1199,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1230,20 +1227,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1255,20 +1252,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1283,20 +1280,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1314,17 +1311,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1345,17 +1342,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1367,17 +1364,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1389,17 +1386,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1411,17 +1408,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1433,17 +1430,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1458,17 +1455,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1483,17 +1480,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1505,17 +1502,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1527,17 +1524,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1549,17 +1546,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1571,17 +1568,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1593,17 +1590,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1615,17 +1612,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1643,7 +1640,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1668,6 +1668,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif index 16028c0e8..843601633 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif @@ -787,13 +787,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +802,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +827,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -861,17 +858,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -886,20 +883,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -914,20 +911,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -945,20 +942,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -973,20 +970,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1004,20 +1001,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1029,20 +1026,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1057,20 +1054,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1091,20 +1088,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1122,20 +1119,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1147,20 +1144,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1178,20 +1175,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1203,20 +1200,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1231,20 +1228,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1256,20 +1253,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1284,20 +1281,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1315,17 +1312,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1456,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1484,17 +1481,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3004", + "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "GenerateRequiredSymbolFormat" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1594,17 +1591,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1616,17 +1613,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1644,7 +1641,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1669,6 +1669,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif index 988b54661..87314dd22 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif index 989407353..a5ab148a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif @@ -50,6 +50,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif index 03618d784..e498ed1b9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif index 60341f525..c0fa83431 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif @@ -766,13 +766,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +781,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +806,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +837,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +862,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +890,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +921,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +949,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +980,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1005,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1033,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1067,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1098,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1123,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1154,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1179,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1207,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1232,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1260,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1291,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1322,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1344,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1366,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1388,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1410,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1432,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1454,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1482,17 +1479,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1507,17 +1504,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1529,17 +1526,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1551,17 +1548,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1573,17 +1570,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1601,7 +1598,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1626,6 +1626,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif index abecdfb73..9c7fc0650 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif @@ -765,13 +765,10 @@ "rules": [ { "id": "BA2001", + "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +780,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "LoadImageAboveFourGigabyteAddress", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", + "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +805,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotIncorporateVulnerableDependencies", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", + "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +836,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSecureSourceCodeHashing" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + } }, { "id": "BA2005", + "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +861,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotShipVulnerableBinaries", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", + "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +889,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "BuildWithSecureTools", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", + "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +920,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableCriticalCompilerWarnings", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", + "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +948,20 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "name": "EnableControlFlowGuard", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", + "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +979,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAddressSpaceLayoutRandomization", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", + "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1004,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkImportsSectionAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", + "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1032,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", + "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1066,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotModifyStackProtectionCookie", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", + "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1097,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "InitializeStackProtection", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", + "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1122,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotDisableStackProtectionForFunctions", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", + "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1153,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableHighEntropyVirtualAddresses", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", + "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1178,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "MarkImageAsNXCompatible", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", + "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1206,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSafeSEH", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", + "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1231,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsShared", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", + "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1259,20 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkWritableSectionsAsExecutable", + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", + "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1290,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "SignSecurely" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + } }, { "id": "BA2024", + "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1321,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableSpectreMitigations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + } }, { "id": "BA2025", + "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1343,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableShadowStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + } }, { "id": "BA2026", + "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1365,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableAdditionalSdlSecurityChecks" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + } }, { "id": "BA3003", + "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1387,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackProtector" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + } }, { "id": "BA3005", + "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1409,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableStackClashProtection" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + } }, { "id": "BA5001", + "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1431,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutableMachO" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA5002", + "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1453,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotAllowExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + } }, { "id": "BA3001", + "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1478,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnablePositionIndependentExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + } }, { "id": "BA3002", + "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1503,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "DoNotMarkStackAsExecutable" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + } }, { "id": "BA3006", + "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1525,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableNonExecutableStack" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + } }, { "id": "BA3010", + "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1547,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableReadOnlyRelocations" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + } }, { "id": "BA3011", + "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1569,17 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "EnableBindNow" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + } }, { "id": "BA3030", + "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,7 +1597,10 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "name": "UseCheckedFunctionsWithGcc" + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + } } ], "properties": { @@ -1625,6 +1625,7 @@ } } ], + "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.exe b/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.exe new file mode 100644 index 0000000000000000000000000000000000000000..83ca050b552274985f65a903f56b74b95226789e GIT binary patch literal 1178624 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 z

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

o2!xVSnJPVDlE~7XF$xA>at1A-JBJoy^Iwq}U zhQ(TP`a!P6SE!`y&u|S=w!sMLG@?4)bENxqPi5z>B@=FQ2

4q)rX+z8FK;j?bvS3Cod+lE{^8DoOUr&E? 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 b0*weXBG8CHBLa;GG$PQ5KqCTw4-xne*sqkf literal 0 HcmV?d00001 diff --git a/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.pdb b/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestsData/BA2006.BuildWithSecureTools/Pass/clangcl.pe.cpp.codeview.pdb new file mode 100644 index 0000000000000000000000000000000000000000..f6fe6f42a24db8681f909d23483c14334252fc98 GIT binary patch literal 6270976 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 |_tA^do*>#84id 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

0H{lkDvqm-p8)yY>K-@#5G3OBbMdfwp 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%0D!^>TwSYQc1<(id1FLM<0)xOzJKCo}AJ7lb`arvZ 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

}{b(Be1adO`fCy(VXH&v8eEj%xm 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 z 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

W&>aUuW;;=ra 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 z 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%0A4%UD&M@83Xn6eu_t&WYruA88opc^` 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 Awg3PC literal 0 HcmV?d00001 From af6ff95e94c45281e81f6b3f5783108534ab9024 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Thu, 16 Dec 2021 17:04:43 -0800 Subject: [PATCH 03/10] add Release History --- src/ReleaseHistory.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ReleaseHistory.md b/src/ReleaseHistory.md index cf2ef2b43..b1e07c54c 100644 --- a/src/ReleaseHistory.md +++ b/src/ReleaseHistory.md @@ -2,6 +2,8 @@ ## Unreleased +* BUGFIX: Fix Error BA2006: '...' was compiled with one or more modules which were not built using minimum required tool versions [533](https://github.com/microsoft/binskim/pull/533) + ## **v1.9.0** [NuGet Package](https://www.nuget.org/packages/Microsoft.CodeAnalysis.BinSkim/1.9.0) * BUGFIX: Fix telemetry session creation. [515](https://github.com/microsoft/binskim/pull/515) From 02f655652b6840a94be5a489bad5720ff892f0d3 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Thu, 6 Jan 2022 18:44:28 -0800 Subject: [PATCH 04/10] update comments with date and person --- .../PERules/BA2006.BuildWithSecureTools.cs | 72 ++++++++++--------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs index e3bce0d4f..c8dc7fd81 100644 --- a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs +++ b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs @@ -119,7 +119,9 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte if (omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftC && omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftCxx) { - // TODO: https://github.com/Microsoft/binskim/issues/114 + // TODO: MikeFan (1/6/2022) + // We need to take a step back and comprehensively review our compiler/language support. + // https://github.com/Microsoft/binskim/issues/114 continue; } @@ -139,37 +141,43 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte break; } - //case Language.MASM: - //{ - // minCompilerVersion = - // context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.MASM)]; - // break; - //} - - //case Language.CVTRES: - //{ - // minCompilerVersion = - // context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.CVTRES)]; - // break; - //} - - //case Language.CSharp: - //{ - // minCompilerVersion = - // context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.CSharp)]; - // break; - //} - - // Language data is not always included if it is only compiled with SymTagCompiland without SymTagCompilandDetails - // https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/compilanddetails?view=vs-2022 - // Compiland information is split between symbols with a SymTagCompiland tag (low detail) - // and a SymTagCompilandDetails tag (high detail). - //case Language.Unknown: - //{ - // minCompilerVersion = - // context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.Unknown)]; - // break; - //} + /* + TODO: MikeFan (1/6/2022) + We need to take a step back and comprehensively review our compiler/language support. + https://github.com/Microsoft/binskim/issues/114 + + case Language.MASM: + { + minCompilerVersion = + context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.MASM)]; + break; + } + + case Language.CVTRES: + { + minCompilerVersion = + context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.CVTRES)]; + break; + } + + case Language.CSharp: + { + minCompilerVersion = + context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.CSharp)]; + break; + } + + Language data is not always included if it is only compiled with SymTagCompiland without SymTagCompilandDetails + https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/compilanddetails?view=vs-2022 + Compiland information is split between symbols with a SymTagCompiland tag (low detail) + and a SymTagCompilandDetails tag (high detail). + case Language.Unknown: + { + minCompilerVersion = + context.Policy.GetProperty(MinimumToolVersions)[nameof(Language.Unknown)]; + break; + } + */ default: { From a9fc939affb339421a4bf072d97b88ef9c3b05ab Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Fri, 7 Jan 2022 00:10:41 -0800 Subject: [PATCH 05/10] fix the SDK, point Binskim to the fixed branch, run rebaseline, so 1. check if fix works 2. now we can review the actual change without noise --- .../Expected/BinSkim.win-x64.ni.dll.sarif | 397 ++++++++++-------- .../Expected/BinSkim.win-x86.ni.dll.sarif | 397 ++++++++++-------- .../Expected/Binskim.linux-x64.dll.sarif | 385 ++++++++++------- .../Expected/Binskim.win-x64.RTR.dll.sarif | 397 ++++++++++-------- .../Expected/Binskim.win-x64.dll.sarif | 385 ++++++++++------- .../Expected/Binskim.win-x86.RTR.dll.sarif | 397 ++++++++++-------- .../Expected/Binskim.win-x86.dll.sarif | 385 ++++++++++------- ...rupted_Native_x86_VS2013_Default.exe.sarif | 1 - ...ore_RTR_linux-x64_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...tCore_RTR_win-x64_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...tCore_RTR_win-x86_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...NetCore_linux-x64_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...otNetCore_win-x64_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...otNetCore_win-x64_VS2019_Default.exe.sarif | 397 ++++++++++-------- ...otNetCore_win-x86_VS2019_Default.dll.sarif | 397 ++++++++++-------- ...InteropAssemblyForAtlTestLibrary.dll.sarif | 385 ++++++++++------- .../Expected/ManagedResourcesOnly.dll.sarif | 385 ++++++++++------- ...aged_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif | 397 ++++++++++-------- ...anaged_AnyCPU_VS2017_Prefer32Bit.exe.sarif | 397 ++++++++++-------- .../Managed_x64_VS2015_FSharp.exe.sarif | 397 ++++++++++-------- ...VS2019_CSharp_DebugType_Embedded.dll.sarif | 397 ++++++++++-------- ...x64_VS2019_CSharp_DebugType_Full.dll.sarif | 397 ++++++++++-------- ...x64_VS2019_CSharp_DebugType_None.dll.sarif | 385 ++++++++++------- ..._VS2019_CSharp_DebugType_PdbOnly.dll.sarif | 397 ++++++++++-------- ...VS2019_CSharp_DebugType_Portable.dll.sarif | 397 ++++++++++-------- ...x64_VS2019_VB_DebugType_Embedded.dll.sarif | 397 ++++++++++-------- ...ged_x64_VS2019_VB_DebugType_Full.dll.sarif | 397 ++++++++++-------- ...ged_x64_VS2019_VB_DebugType_None.dll.sarif | 385 ++++++++++------- ..._x64_VS2019_VB_DebugType_PdbOnly.dll.sarif | 397 ++++++++++-------- ...x64_VS2019_VB_DebugType_Portable.dll.sarif | 397 ++++++++++-------- .../Expected/Managed_x86_VS2013_Wpf.exe.sarif | 397 ++++++++++-------- .../Managed_x86_VS2015_FSharp.dll.sarif | 397 ++++++++++-------- .../MixedMode_x64_VS2013_Default.dll.sarif | 397 ++++++++++-------- .../MixedMode_x64_VS2013_NoPdb.exe.sarif | 277 +++++++----- .../MixedMode_x64_VS2015_Default.exe.sarif | 397 ++++++++++-------- ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 397 ++++++++++-------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 397 ++++++++++-------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 397 ++++++++++-------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 277 +++++++----- .../MixedMode_x86_VS2013_Default.exe.sarif | 397 ++++++++++-------- .../MixedMode_x86_VS2013_MissingPdb.dll.sarif | 277 +++++++----- .../MixedMode_x86_VS2015_Default.exe.sarif | 397 ++++++++++-------- ...ve_ARM_VS2015_CvtresResourceOnly.dll.sarif | 385 ++++++++++------- .../Native_x64_VS2013_Default.dll.sarif | 397 ++++++++++-------- ...ve_x64_VS2015_CvtresResourceOnly.dll.sarif | 385 ++++++++++------- .../Native_x64_VS2015_Default.dll.sarif | 397 ++++++++++-------- ...ve_x64_VS2019_Atl_NoPdbGenerated.dll.sarif | 277 +++++++----- ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 397 ++++++++++-------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 397 ++++++++++-------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 397 ++++++++++-------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 277 +++++++----- .../Native_x64_VS2019_SDL_Enabled.exe.sarif | 397 ++++++++++-------- ...tive_x64_VSCode_Rust_DebugInfo_0.exe.sarif | 397 ++++++++++-------- ...tive_x64_VSCode_Rust_DebugInfo_1.exe.sarif | 397 ++++++++++-------- ...tive_x64_VSCode_Rust_DebugInfo_2.exe.sarif | 397 ++++++++++-------- .../Native_x86_VS2012_SDL_Enabled.exe.sarif | 397 ++++++++++-------- .../Native_x86_VS2013_Default.exe.sarif | 397 ++++++++++-------- .../Native_x86_VS2013_PdbMissing.exe.sarif | 277 +++++++----- .../Native_x86_VS2013_ResourceOnly.dll.sarif | 397 ++++++++++-------- ...Native_x86_VS2015_AtlProxyStubPS.dll.sarif | 397 ++++++++++-------- ...ve_x86_VS2015_CvtresResourceOnly.dll.sarif | 385 ++++++++++------- .../Native_x86_VS2015_Default.exe.sarif | 397 ++++++++++-------- .../Native_x86_VS2015_Default_Debug.dll.sarif | 397 ++++++++++-------- ...ve_x86_VS2017_15.5.4_PdbStripped.dll.sarif | 277 +++++++----- .../Native_x86_VS2019_SDL_Enabled.exe.sarif | 397 ++++++++++-------- .../Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif | 397 ++++++++++-------- .../Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif | 313 ++++++++------ .../Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif | 277 +++++++----- .../Expected/Uwp_ARM_VS2017_VB.dll.sarif | 397 ++++++++++-------- ...wp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif | 397 ++++++++++-------- .../Uwp_x64_VS2015_DefaultBlankApp.dll.sarif | 313 ++++++++------ .../Uwp_x64_VS2015_DefaultBlankApp.exe.sarif | 277 +++++++----- .../Expected/Uwp_x64_VS2017_Cpp.dll.sarif | 397 ++++++++++-------- .../Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif | 397 ++++++++++-------- .../Uwp_x86_VS2015_DefaultBlankApp.dll.sarif | 313 ++++++++------ .../Uwp_x86_VS2015_DefaultBlankApp.exe.sarif | 277 +++++++----- .../Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif | 397 ++++++++++-------- .../Wix_3.11.1_VS2017_Bootstrapper.exe.sarif | 397 ++++++++++-------- .../Expected/clang.default_compilation.sarif | 385 ++++++++++------- .../Expected/clang.elf.objectivec.dwarf.sarif | 397 ++++++++++-------- .../Expected/clang.execstack.sarif | 385 ++++++++++------- .../Expected/clang.execstack.so.sarif | 385 ++++++++++------- .../Expected/clang.immediate_binding.sarif | 385 ++++++++++------- .../Expected/clang.no_immediate_binding.sarif | 385 ++++++++++------- .../Expected/clang.no_stack_protector.sarif | 385 ++++++++++------- .../Expected/clang.noexecstack.sarif | 385 ++++++++++------- .../Expected/clang.noexecstack.so.sarif | 385 ++++++++++------- .../Expected/clang.non_pie_executable.sarif | 385 ++++++++++------- .../Expected/clang.object_file.o.sarif | 385 ++++++++++------- .../Expected/clang.pie_executable.sarif | 385 ++++++++++------- .../Expected/clang.relocationsro.sarif | 385 ++++++++++------- .../Expected/clang.relocationsrw.sarif | 385 ++++++++++------- .../Expected/clang.shared_library.so.sarif | 385 ++++++++++------- .../Expected/clang.stack_protector.a.sarif | 1 - .../Expected/clang.stack_protector.sarif | 385 ++++++++++------- .../Expected/clang.stack_protector.so.sarif | 385 ++++++++++------- .../clangcl.pe.cpp.codeview.exe.sarif | 397 ++++++++++-------- .../Expected/gcc.default_compilation.sarif | 385 ++++++++++------- ...rongsspbuffersize8+fnostackprotector.sarif | 397 ++++++++++-------- .../Expected/gcc.execstack.sarif | 385 ++++++++++------- .../Expected/gcc.execstack.so.sarif | 385 ++++++++++------- .../Expected/gcc.fortified.sarif | 385 ++++++++++------- .../Expected/gcc.gsplitdwarf.5.dwo.sarif | 397 ++++++++++-------- .../Expected/gcc.gsplitdwarf.5.sarif | 397 ++++++++++-------- ...oworld.4.o.no-stack-clash-protection.sarif | 397 ++++++++++-------- ...oworld.5.o.no-stack-clash-protection.sarif | 397 ++++++++++-------- .../gcc.helloworld.execstack.5.o.sarif | 397 ++++++++++-------- .../Expected/gcc.helloworld.nodwarf.sarif | 385 ++++++++++------- .../gcc.helloworld.noexecstack.5.o.sarif | 397 ++++++++++-------- .../Expected/gcc.immediate_binding.sarif | 385 ++++++++++------- .../gcc.no_fortification_required.sarif | 385 ++++++++++------- .../Expected/gcc.no_immediate_binding.sarif | 385 ++++++++++------- .../Expected/gcc.no_stack_protector.sarif | 385 ++++++++++------- .../Expected/gcc.noexecstack.sarif | 385 ++++++++++------- .../Expected/gcc.noexecstack.so.sarif | 385 ++++++++++------- .../Expected/gcc.non_pie_executable.sarif | 385 ++++++++++------- ...objcopy.stripall.addgnudebuglink.dbg.sarif | 397 ++++++++++-------- ...gcc.objcopy.stripall.addgnudebuglink.sarif | 385 ++++++++++------- .../Expected/gcc.object_file.o.sarif | 385 ++++++++++------- .../gcc.pe.objectivec.dwarf.exe.sarif | 277 +++++++----- .../Expected/gcc.pie_executable.sarif | 385 ++++++++++------- .../Expected/gcc.relocationsro.sarif | 385 ++++++++++------- .../Expected/gcc.relocationsrw.sarif | 385 ++++++++++------- .../Expected/gcc.requiredsymbol.4.o.sarif | 397 ++++++++++-------- .../Expected/gcc.requiredsymbol.5.o.sarif | 397 ++++++++++-------- .../Expected/gcc.shared_library.so.sarif | 385 ++++++++++------- .../Expected/gcc.stack_protector.a.sarif | 1 - .../Expected/gcc.stack_protector.sarif | 385 ++++++++++------- .../Expected/gcc.stack_protector.so.sarif | 385 ++++++++++------- .../Expected/gcc.unfortified.sarif | 385 ++++++++++------- 130 files changed, 28091 insertions(+), 20195 deletions(-) diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif index bb6cbc52c..65d6d9d03 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +841,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -861,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -920,20 +931,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +961,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -979,20 +994,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1004,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1035,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1060,20 +1081,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1088,20 +1111,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1122,17 +1147,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1144,17 +1171,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1166,17 +1195,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1191,17 +1222,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1216,17 +1249,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1238,17 +1273,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1260,17 +1297,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1282,17 +1321,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1304,17 +1345,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1326,17 +1369,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1348,17 +1393,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1376,17 +1423,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1398,17 +1447,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1420,17 +1471,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1442,20 +1495,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1470,20 +1525,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1501,20 +1558,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1526,20 +1585,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1560,20 +1621,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1585,20 +1648,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1613,20 +1678,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif index 1f7827462..ebcc7c5d5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -859,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -884,20 +893,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -915,20 +926,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -943,20 +956,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1027,20 +1046,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1092,17 +1115,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1114,17 +1139,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1136,17 +1163,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1161,17 +1190,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1186,17 +1217,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1208,17 +1241,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1230,17 +1265,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1252,17 +1289,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1274,17 +1313,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1296,17 +1337,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1318,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1346,17 +1391,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1368,17 +1415,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1390,17 +1439,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1415,20 +1466,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1446,20 +1499,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1471,20 +1526,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif index 8eb5f44e6..6ec50de89 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif @@ -772,10 +772,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +790,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +817,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -840,20 +847,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -871,20 +880,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -899,20 +910,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -952,20 +967,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -986,20 +1003,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1017,20 +1036,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1042,20 +1063,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1073,20 +1096,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1160,17 +1189,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1182,17 +1213,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1204,17 +1237,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1229,17 +1264,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1254,17 +1291,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1276,17 +1315,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1298,17 +1339,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1320,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1342,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1364,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1386,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1414,17 +1465,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1436,17 +1489,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1458,17 +1513,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1483,20 +1540,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1514,20 +1573,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1539,20 +1600,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1567,20 +1630,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1646,7 +1710,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif index be14e14d1..64053d782 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +841,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -861,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -920,20 +931,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +961,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -979,20 +994,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1004,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1035,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1060,20 +1081,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1088,20 +1111,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1122,17 +1147,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1144,17 +1171,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1166,17 +1195,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1191,17 +1222,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1216,17 +1249,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1238,17 +1273,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1260,17 +1297,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1282,17 +1321,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1304,17 +1345,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1326,17 +1369,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1348,17 +1393,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1376,17 +1423,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1398,17 +1447,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1420,17 +1471,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1442,20 +1495,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1470,20 +1525,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1501,20 +1558,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1526,20 +1585,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1560,20 +1621,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1585,20 +1648,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1613,20 +1678,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif index bb317f7e7..79b1d4cb0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif @@ -772,10 +772,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -787,20 +790,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -812,20 +817,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -840,20 +847,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -871,20 +880,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -899,20 +910,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -952,20 +967,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -986,20 +1003,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1017,20 +1036,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1042,20 +1063,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1073,20 +1096,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1160,17 +1189,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1182,17 +1213,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1204,17 +1237,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1229,17 +1264,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1254,17 +1291,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1276,17 +1315,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1298,17 +1339,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1320,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1342,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1364,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1386,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1414,17 +1465,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1436,17 +1489,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1458,17 +1513,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1483,20 +1540,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1514,20 +1573,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1539,20 +1600,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1567,20 +1630,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1646,7 +1710,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif index e43aaf0d1..50fe6d486 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -859,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -884,20 +893,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -915,20 +926,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -943,20 +956,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1027,20 +1046,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1092,17 +1115,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1114,17 +1139,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1136,17 +1163,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1161,17 +1190,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1186,17 +1217,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1208,17 +1241,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1230,17 +1265,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1252,17 +1289,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1274,17 +1313,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1296,17 +1337,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1318,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1346,17 +1391,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1368,17 +1415,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1390,17 +1439,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1415,20 +1466,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1446,20 +1499,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1471,20 +1526,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif index 92dda9ce4..933aa32a2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -836,20 +843,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -867,20 +876,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -895,20 +906,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +963,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1013,20 +1032,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1038,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1103,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1125,17 +1152,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1147,17 +1176,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1172,17 +1203,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1197,17 +1230,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1219,17 +1254,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1241,17 +1278,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1263,17 +1302,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1285,17 +1326,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1307,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1329,17 +1374,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1357,17 +1404,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1379,17 +1428,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1401,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1426,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1457,20 +1512,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1482,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1510,20 +1569,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1563,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1594,10 +1659,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1642,7 +1706,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif index 657da81f3..1ed0528af 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Corrupted_Native_x86_VS2013_Default.exe.sarif @@ -50,7 +50,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif index 737c671a7..9d15fcbc5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif @@ -795,10 +795,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -810,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -835,20 +840,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -894,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -922,20 +933,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -947,20 +960,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -975,20 +990,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1009,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1040,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1065,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1096,20 +1119,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1121,20 +1146,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1149,20 +1176,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1183,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1205,17 +1236,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1227,17 +1260,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1252,17 +1287,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1277,17 +1314,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1299,17 +1338,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1437,17 +1488,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1512,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1481,17 +1536,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1565,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1590,20 +1653,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1618,20 +1683,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1649,10 +1716,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1677,7 +1743,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif index ee7b4cd70..56b3adc58 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif @@ -795,10 +795,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -810,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -835,20 +840,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -894,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -922,20 +933,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -947,20 +960,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -975,20 +990,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1009,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1040,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1065,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1096,20 +1119,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1121,20 +1146,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1149,20 +1176,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1183,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1205,17 +1236,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1227,17 +1260,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1252,17 +1287,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1277,17 +1314,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1299,17 +1338,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1437,17 +1488,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1512,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1481,17 +1536,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1565,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1590,20 +1653,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1618,20 +1683,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1649,10 +1716,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1677,7 +1743,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif index 9f25db574..f1bda8df7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif index ddcf41a4f..1c5b99a21 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif @@ -795,10 +795,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -810,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -835,20 +840,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -894,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -922,20 +933,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -947,20 +960,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -975,20 +990,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1009,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1040,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1065,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1096,20 +1119,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1121,20 +1146,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1149,20 +1176,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1183,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1205,17 +1236,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1227,17 +1260,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1252,17 +1287,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1277,17 +1314,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1299,17 +1338,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1437,17 +1488,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1512,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1481,17 +1536,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1565,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1590,20 +1653,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1618,20 +1683,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1649,10 +1716,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1677,7 +1743,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif index 3cb656772..daeb0d495 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif @@ -795,10 +795,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -810,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -835,20 +840,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -894,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -922,20 +933,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -947,20 +960,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -975,20 +990,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1009,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1040,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1065,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1096,20 +1119,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1121,20 +1146,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1149,20 +1176,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1183,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1205,17 +1236,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1227,17 +1260,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1252,17 +1287,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1277,17 +1314,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1299,17 +1338,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1437,17 +1488,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1459,17 +1512,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1481,17 +1536,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1565,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1590,20 +1653,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1618,20 +1683,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1649,10 +1716,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1677,7 +1743,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif index 4cb3fc583..c04c4b3dd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -832,17 +837,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -857,20 +864,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -888,20 +897,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -916,20 +927,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -947,20 +960,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -972,20 +987,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -997,20 +1014,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1025,20 +1044,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1059,17 +1080,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1081,17 +1104,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1103,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1128,17 +1155,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1153,17 +1182,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1175,17 +1206,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1197,17 +1230,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1219,17 +1254,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1241,17 +1278,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1263,17 +1302,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1285,17 +1326,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1313,17 +1356,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1335,17 +1380,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1357,17 +1404,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1379,20 +1428,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1407,20 +1458,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1435,20 +1488,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1466,20 +1521,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1491,20 +1548,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1525,20 +1584,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1556,20 +1617,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1581,20 +1644,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1609,20 +1674,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif index 9a11763c7..60c860595 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif index a548c6db5..29bb9a1ec 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -836,20 +843,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -867,20 +876,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -895,20 +906,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +963,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1013,20 +1032,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1038,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1103,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1125,17 +1152,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1147,17 +1176,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1172,17 +1203,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1197,17 +1230,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1219,17 +1254,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1241,17 +1278,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1263,17 +1302,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1285,17 +1326,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1307,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1329,17 +1374,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1357,17 +1404,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1379,17 +1428,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1401,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1426,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1457,20 +1512,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1482,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1510,20 +1569,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1563,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1594,10 +1659,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1642,7 +1706,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif index 424eccf83..9cb9f5861 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif @@ -771,10 +771,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -786,20 +789,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -811,20 +816,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -839,20 +846,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -870,20 +879,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -898,20 +909,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -951,20 +966,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -985,20 +1002,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1016,20 +1035,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1041,20 +1062,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1072,20 +1095,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1159,17 +1188,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1181,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1203,17 +1236,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1228,17 +1263,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1253,17 +1290,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1275,17 +1314,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1297,17 +1338,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1319,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1341,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1363,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1385,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1413,17 +1464,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1435,17 +1488,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1457,17 +1512,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1482,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1513,20 +1572,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1599,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1566,20 +1629,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1645,7 +1709,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif index f2d68c0aa..b503fe5aa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif @@ -785,10 +785,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -800,20 +803,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -825,20 +830,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -853,20 +860,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -884,20 +893,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -912,20 +923,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -937,20 +950,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -965,20 +980,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -999,20 +1016,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1030,20 +1049,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1055,20 +1076,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1089,17 +1112,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1111,17 +1136,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1133,17 +1160,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1158,17 +1187,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1183,17 +1214,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1205,17 +1238,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1227,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1249,17 +1286,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1271,17 +1310,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1293,17 +1334,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1315,17 +1358,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1343,17 +1388,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1365,17 +1412,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1387,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1415,17 +1466,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1440,20 +1493,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1471,20 +1526,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1502,20 +1559,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1527,20 +1586,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1555,20 +1616,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1580,20 +1643,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1608,20 +1673,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1639,10 +1706,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1667,7 +1733,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif index 42594fd5a..beb05901c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -856,20 +863,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -887,20 +896,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -915,20 +926,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -940,20 +953,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -968,20 +983,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1033,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1089,20 +1112,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1123,17 +1148,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1145,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1167,17 +1196,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1192,17 +1223,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1217,17 +1250,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1239,17 +1274,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1261,17 +1298,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1283,17 +1322,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1305,17 +1346,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1327,17 +1370,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1349,17 +1394,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1377,17 +1424,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1399,17 +1448,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1421,17 +1472,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1449,17 +1502,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1474,20 +1529,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif index 746bbff38..89e03df15 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +835,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -858,20 +865,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -889,20 +898,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -917,20 +928,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -942,20 +955,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -970,20 +985,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1004,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1035,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1060,20 +1081,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1085,20 +1108,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1113,20 +1138,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1147,17 +1174,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1169,17 +1198,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1191,17 +1222,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1216,17 +1249,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1241,17 +1276,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1263,17 +1300,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1285,17 +1324,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1307,17 +1348,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1329,17 +1372,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1351,17 +1396,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1373,17 +1420,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1401,17 +1450,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1423,17 +1474,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1445,17 +1498,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1473,17 +1528,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1498,20 +1555,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1529,20 +1588,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1560,20 +1621,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1585,20 +1648,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1613,20 +1678,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif index 409780d31..6c33f0790 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif index 425c672a8..cacfafb66 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif index 5e422baa5..87178f04a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -836,20 +843,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -867,20 +876,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -895,20 +906,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +963,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1013,20 +1032,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1038,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1103,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1125,17 +1152,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1147,17 +1176,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1172,17 +1203,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1197,17 +1230,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1219,17 +1254,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1241,17 +1278,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1263,17 +1302,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1285,17 +1326,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1307,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1329,17 +1374,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1357,17 +1404,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1379,17 +1428,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1401,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1426,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1457,20 +1512,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1482,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1510,20 +1569,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1563,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1594,10 +1659,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1642,7 +1706,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif index c4762c40d..2545c7a7d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif index 07122911d..232ddc41f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif index ae31c8c2f..de3e04dfc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif index 5451af733..366d4741c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif index 28542b0c5..3b1516b1b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -836,20 +843,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -867,20 +876,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -895,20 +906,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +963,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1013,20 +1032,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1038,20 +1059,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1103,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1125,17 +1152,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1147,17 +1176,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1172,17 +1203,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1197,17 +1230,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1219,17 +1254,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1241,17 +1278,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1263,17 +1302,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1285,17 +1326,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1307,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1329,17 +1374,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1357,17 +1404,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1379,17 +1428,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1401,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1426,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1457,20 +1512,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1482,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1510,20 +1569,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1563,20 +1626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1594,10 +1659,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1642,7 +1706,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif index bff3c2ac8..cf3650996 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif index 8838bed96..4aadd4f96 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -859,20 +866,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -890,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -918,20 +929,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -943,20 +956,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1036,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1061,20 +1082,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1126,17 +1151,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1148,17 +1175,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1170,17 +1199,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1195,17 +1226,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1220,17 +1253,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1242,17 +1277,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1264,17 +1301,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1286,17 +1325,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1308,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1330,17 +1373,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1352,17 +1397,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1380,17 +1427,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1402,17 +1451,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1424,17 +1475,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1561,20 +1622,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1586,20 +1649,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1614,20 +1679,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif index 5bdec020b..e5c573d30 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -856,20 +863,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -887,20 +896,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -915,20 +926,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -940,20 +953,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -968,20 +983,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1033,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1089,20 +1112,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1123,17 +1148,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1145,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1167,17 +1196,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1192,17 +1223,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1217,17 +1250,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1239,17 +1274,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1261,17 +1298,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1283,17 +1322,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1305,17 +1346,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1327,17 +1370,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1349,17 +1394,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1377,17 +1424,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1399,17 +1448,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1421,17 +1472,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1449,17 +1502,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1474,20 +1529,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif index a90dc7ec7..419e0dcdc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -856,20 +863,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -887,20 +896,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -915,20 +926,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -940,20 +953,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -968,20 +983,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1033,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1089,20 +1112,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1123,17 +1148,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1145,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1167,17 +1196,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1192,17 +1223,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1217,17 +1250,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1239,17 +1274,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1261,17 +1298,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1283,17 +1322,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1305,17 +1346,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1327,17 +1370,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1349,17 +1394,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1377,17 +1424,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1399,17 +1448,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1421,17 +1472,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1449,17 +1502,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1474,20 +1529,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif index 6b7d4c235..5c7311b7b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif @@ -789,10 +789,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -807,20 +810,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -838,20 +843,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -891,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -919,17 +930,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -944,17 +957,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -966,17 +981,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -988,17 +1005,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1010,17 +1029,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1032,17 +1053,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1054,17 +1077,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1076,17 +1101,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1104,17 +1131,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1126,17 +1155,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1148,17 +1179,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1170,20 +1203,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1195,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1226,17 +1263,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1251,20 +1290,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1279,20 +1320,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1310,20 +1353,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1341,20 +1386,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1366,20 +1413,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1394,20 +1443,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1428,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1459,20 +1512,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1484,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1662,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,10 +1710,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1671,7 +1737,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif index 61a2ac74f..8f997e867 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif @@ -548,10 +548,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -566,20 +569,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -591,20 +596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -619,20 +626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -647,17 +656,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -672,17 +683,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -694,17 +707,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -716,17 +731,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -738,17 +755,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -760,17 +779,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -782,17 +803,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -804,17 +827,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -832,17 +857,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -854,17 +881,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -876,17 +905,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -898,20 +929,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -926,20 +959,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -957,20 +992,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -982,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1016,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1047,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1072,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1100,20 +1145,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1131,10 +1178,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1179,7 +1225,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif index 5e2b8f9df..d8fb13d6d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -805,20 +808,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -830,20 +835,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -858,20 +865,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -886,17 +895,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -911,17 +922,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -933,17 +946,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -955,17 +970,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -977,17 +994,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -999,17 +1018,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1021,17 +1042,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1043,17 +1066,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1071,17 +1096,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1093,17 +1120,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1115,17 +1144,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1137,20 +1168,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1162,20 +1195,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1193,17 +1228,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1218,20 +1255,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1246,20 +1285,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1277,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1308,20 +1351,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1333,20 +1378,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1361,20 +1408,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1426,20 +1477,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1451,20 +1504,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1482,20 +1537,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1507,20 +1564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1594,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1566,17 +1627,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1597,17 +1660,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1619,17 +1684,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index 62f8441bc..c3858194b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -808,20 +811,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -839,20 +844,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -864,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -920,17 +931,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -945,17 +958,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -967,17 +982,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -989,17 +1006,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1011,17 +1030,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1033,17 +1054,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1055,17 +1078,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1077,17 +1102,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1105,17 +1132,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1127,17 +1156,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1149,17 +1180,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1171,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1196,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1227,17 +1264,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1252,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1280,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1311,20 +1354,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1342,20 +1387,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1367,20 +1414,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1429,20 +1480,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1460,20 +1513,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1485,20 +1540,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1567,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1597,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1663,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1687,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index c4872d266..281195b9d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -808,20 +811,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -839,20 +844,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -864,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -920,17 +931,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -945,17 +958,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -967,17 +982,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -989,17 +1006,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1011,17 +1030,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1033,17 +1054,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1055,17 +1078,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1077,17 +1102,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1105,17 +1132,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1127,17 +1156,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1149,17 +1180,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1171,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1196,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1227,17 +1264,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1252,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1280,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1311,20 +1354,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1342,20 +1387,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1367,20 +1414,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1429,20 +1480,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1460,20 +1513,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1485,20 +1540,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1567,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1597,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1663,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1687,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index 31a81fb66..e8753fd8d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -808,20 +811,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -839,20 +844,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -864,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -920,17 +931,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -945,17 +958,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -967,17 +982,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -989,17 +1006,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1011,17 +1030,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1033,17 +1054,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1055,17 +1078,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1077,17 +1102,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1105,17 +1132,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1127,17 +1156,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1149,17 +1180,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1171,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1196,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1227,17 +1264,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1252,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1280,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1311,20 +1354,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1342,20 +1387,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1367,20 +1414,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1429,20 +1480,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1460,20 +1513,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1485,20 +1540,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1510,20 +1567,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1538,20 +1597,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1600,17 +1663,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1622,17 +1687,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index 7c214e370..9fd342723 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -550,10 +550,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -568,20 +571,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -599,20 +604,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -624,20 +631,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -652,20 +661,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -680,17 +691,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -705,17 +718,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -727,17 +742,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -749,17 +766,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -771,17 +790,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -793,17 +814,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -815,17 +838,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -837,17 +862,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -865,17 +892,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -887,17 +916,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -909,17 +940,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -931,20 +964,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -959,20 +994,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -990,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1015,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1049,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1074,20 +1117,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1102,20 +1147,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1133,10 +1180,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1181,7 +1227,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif index 919eb0d23..a9164171b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif @@ -784,10 +784,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -799,20 +802,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -827,20 +832,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -855,17 +862,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -880,17 +889,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -902,17 +913,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -924,17 +937,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -946,17 +961,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -968,17 +985,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -990,17 +1009,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1012,17 +1033,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1040,17 +1063,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1062,17 +1087,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1084,17 +1111,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1106,20 +1135,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1137,17 +1168,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1162,20 +1195,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1190,20 +1225,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1221,20 +1258,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1252,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1277,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1305,20 +1348,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1339,20 +1384,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1370,20 +1417,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1426,20 +1477,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1451,20 +1504,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1479,20 +1534,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1504,20 +1561,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1532,20 +1591,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1563,17 +1624,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1594,17 +1657,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1616,17 +1681,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1638,10 +1705,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1666,7 +1732,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif index 9ab35211b..40d87b128 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif @@ -548,10 +548,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -563,20 +566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -591,20 +596,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -622,20 +629,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -650,17 +659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -675,17 +686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -697,17 +710,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -719,17 +734,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -741,17 +758,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -763,17 +782,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -785,17 +806,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -807,17 +830,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -835,17 +860,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +884,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -879,17 +908,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -904,20 +935,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -935,20 +968,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -960,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -994,20 +1031,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1019,20 +1058,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1047,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1072,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1100,20 +1145,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1131,10 +1178,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1179,7 +1225,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif index 970d913bd..b2567f3bc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif @@ -784,10 +784,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -799,20 +802,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -827,20 +832,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -855,17 +862,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -880,17 +889,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -902,17 +913,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -924,17 +937,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -946,17 +961,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -968,17 +985,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -990,17 +1009,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1012,17 +1033,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1040,17 +1063,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1062,17 +1087,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1084,17 +1111,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1106,20 +1135,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1137,17 +1168,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1162,20 +1195,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1190,20 +1225,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1221,20 +1258,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1252,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1277,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1305,20 +1348,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1339,20 +1384,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1370,20 +1417,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1395,20 +1444,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1426,20 +1477,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1451,20 +1504,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1479,20 +1534,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1504,20 +1561,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1532,20 +1591,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1563,17 +1624,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1594,17 +1657,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1616,17 +1681,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1638,10 +1705,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1666,7 +1732,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif index b06af7739..fc34cd4d0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif @@ -770,10 +770,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -785,20 +788,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -810,20 +815,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -838,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -869,20 +878,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -897,20 +908,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -925,20 +938,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -959,20 +974,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -990,20 +1007,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1015,20 +1034,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1046,20 +1067,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1071,20 +1094,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1099,20 +1124,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1133,17 +1160,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1155,17 +1184,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1177,17 +1208,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1202,17 +1235,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1227,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1249,17 +1286,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1271,17 +1310,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1293,17 +1334,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1315,17 +1358,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1337,17 +1382,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1359,17 +1406,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1387,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1484,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1456,20 +1511,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1487,20 +1544,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1571,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1565,20 +1628,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1644,7 +1708,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif index 1a0b2f52f..17bcc6e90 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -809,20 +812,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -840,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -865,20 +872,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -893,20 +902,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -921,17 +932,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -946,17 +959,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -968,17 +983,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -990,17 +1007,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1012,17 +1031,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1034,17 +1055,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1056,17 +1079,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1078,17 +1103,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1106,17 +1133,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1128,17 +1157,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1150,17 +1181,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1172,20 +1205,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1197,20 +1232,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1228,17 +1265,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1253,20 +1292,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1281,20 +1322,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1312,20 +1355,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1343,20 +1388,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1368,20 +1415,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1396,20 +1445,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1430,20 +1481,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1461,20 +1514,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1486,20 +1541,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1511,20 +1568,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1539,20 +1598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1570,17 +1631,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1601,17 +1664,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1623,17 +1688,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif index 59b669cea..03ce70d6a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif @@ -770,10 +770,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -785,20 +788,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -810,20 +815,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -838,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -869,20 +878,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -897,20 +908,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -925,20 +938,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -959,20 +974,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -990,20 +1007,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1015,20 +1034,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1046,20 +1067,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1071,20 +1094,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1099,20 +1124,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1133,17 +1160,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1155,17 +1184,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1177,17 +1208,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1202,17 +1235,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1227,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1249,17 +1286,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1271,17 +1310,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1293,17 +1334,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1315,17 +1358,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1337,17 +1382,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1359,17 +1406,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1387,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1484,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1456,20 +1511,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1487,20 +1544,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1571,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1565,20 +1628,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1644,7 +1708,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif index 1fd5f10a1..1477baf9f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -809,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -834,20 +839,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -862,20 +869,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -890,17 +899,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -915,17 +926,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -937,17 +950,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -959,17 +974,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -981,17 +998,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1003,17 +1022,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1025,17 +1046,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1047,17 +1070,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1075,17 +1100,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1097,17 +1124,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1119,17 +1148,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1141,20 +1172,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1166,20 +1199,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1197,17 +1232,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1222,20 +1259,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1250,20 +1289,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1281,20 +1322,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1309,20 +1352,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1340,20 +1385,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1365,20 +1412,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1393,20 +1442,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1427,20 +1478,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1458,20 +1511,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1483,20 +1538,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1536,20 +1595,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1567,17 +1628,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1598,17 +1661,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1620,17 +1685,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif index d337b9ff2..0af238da9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif @@ -547,10 +547,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -568,20 +571,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -593,20 +598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -621,20 +628,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -649,17 +658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -674,17 +685,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -696,17 +709,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -718,17 +733,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -740,17 +757,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -762,17 +781,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -784,17 +805,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -806,17 +829,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -834,17 +859,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -856,17 +883,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -878,17 +907,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -900,20 +931,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -928,20 +961,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -956,20 +991,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -987,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1012,20 +1051,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1046,20 +1087,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1071,20 +1114,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1099,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1130,10 +1177,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1178,7 +1224,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index 740d26351..6c3f13f61 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -808,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -833,20 +838,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -861,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -889,17 +898,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -914,17 +925,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -936,17 +949,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -958,17 +973,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -980,17 +997,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1002,17 +1021,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1024,17 +1045,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1046,17 +1069,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1074,17 +1099,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1096,17 +1123,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1118,17 +1147,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1140,20 +1171,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1165,20 +1198,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1196,17 +1231,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1221,20 +1258,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1249,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1280,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1308,20 +1351,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1339,20 +1384,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1364,20 +1411,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1392,20 +1441,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1426,20 +1477,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1457,20 +1510,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1482,20 +1537,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1507,20 +1564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1594,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1566,17 +1627,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1597,17 +1660,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1619,17 +1684,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index a312bbe48..a61379755 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -789,20 +792,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -814,20 +819,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -842,20 +849,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -870,17 +879,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -895,17 +906,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -917,17 +930,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -939,17 +954,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -961,17 +978,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -983,17 +1002,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1005,17 +1026,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1027,17 +1050,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1055,17 +1080,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1077,17 +1104,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1099,17 +1128,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1121,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1146,20 +1179,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1177,17 +1212,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1202,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1230,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1261,20 +1302,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1289,20 +1332,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1320,20 +1365,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1345,20 +1392,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1373,20 +1422,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1407,20 +1458,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1438,20 +1491,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1463,20 +1518,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1488,20 +1545,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1516,20 +1575,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1600,17 +1665,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1622,10 +1689,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1650,7 +1716,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index e0b79a3a0..a5eb4726f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -808,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -833,20 +838,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -861,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -889,17 +898,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -914,17 +925,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -936,17 +949,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -958,17 +973,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -980,17 +997,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1002,17 +1021,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1024,17 +1045,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1046,17 +1069,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1074,17 +1099,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1096,17 +1123,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1118,17 +1147,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1140,20 +1171,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1165,20 +1198,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1196,17 +1231,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1221,20 +1258,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1249,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1280,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1308,20 +1351,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1339,20 +1384,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1364,20 +1411,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1392,20 +1441,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1426,20 +1477,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1457,20 +1510,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1482,20 +1537,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1507,20 +1564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1535,20 +1594,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1566,17 +1627,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1597,17 +1660,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1619,17 +1684,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index 889776c6f..e365fd876 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -547,10 +547,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -568,20 +571,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -593,20 +598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -621,20 +628,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -649,17 +658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -674,17 +685,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -696,17 +709,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -718,17 +733,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -740,17 +757,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -762,17 +781,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -784,17 +805,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -806,17 +829,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -834,17 +859,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -856,17 +883,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -878,17 +907,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -900,20 +931,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -928,20 +961,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -956,20 +991,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -987,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1012,20 +1051,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1046,20 +1087,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1071,20 +1114,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1099,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1130,10 +1177,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1178,7 +1224,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif index f3aa1ef58..062e9c375 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -829,20 +834,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +864,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -882,17 +891,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -904,17 +915,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -926,17 +939,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -948,17 +963,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -970,17 +987,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -992,17 +1011,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1014,17 +1035,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1042,17 +1065,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1064,17 +1089,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1086,17 +1113,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1108,20 +1137,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1133,20 +1164,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1164,17 +1197,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1189,20 +1224,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1217,20 +1254,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1248,20 +1287,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1276,20 +1317,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1307,20 +1350,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1332,20 +1377,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1360,20 +1407,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1394,20 +1443,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1425,20 +1476,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1450,20 +1503,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1481,20 +1536,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1563,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1626,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1683,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif index 70b6b30a1..c0d25e497 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif @@ -761,10 +761,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -776,20 +779,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -804,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -832,17 +839,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -857,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -879,17 +890,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -901,17 +914,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -923,17 +938,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -945,17 +962,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -967,17 +986,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -989,17 +1010,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1017,17 +1040,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1039,17 +1064,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1061,17 +1088,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1083,20 +1112,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1108,20 +1139,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1139,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1164,20 +1199,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1192,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1223,20 +1262,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1251,20 +1292,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1282,20 +1325,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1307,20 +1352,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1335,20 +1382,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1369,20 +1418,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1400,20 +1451,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1425,20 +1478,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1456,20 +1511,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1481,20 +1538,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1568,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1540,17 +1601,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1571,17 +1634,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1593,17 +1658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1615,10 +1682,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1643,7 +1709,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif index c60f2fb69..f80f85b9c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif @@ -783,10 +783,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -798,20 +801,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -854,17 +861,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -879,17 +888,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -901,17 +912,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -923,17 +936,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -945,17 +960,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -967,17 +984,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -989,17 +1008,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1011,17 +1032,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1039,17 +1062,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1061,17 +1086,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1083,17 +1110,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1105,20 +1134,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1130,20 +1161,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1161,17 +1194,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1186,20 +1221,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1214,20 +1251,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1245,20 +1284,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1273,20 +1314,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1304,20 +1347,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1329,20 +1374,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1357,20 +1404,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1391,20 +1440,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1422,20 +1473,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1447,20 +1500,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1478,20 +1533,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1503,20 +1560,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1531,20 +1590,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1562,17 +1623,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1593,17 +1656,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1615,17 +1680,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1637,10 +1704,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1665,7 +1731,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif index d2eb7b22d..27a0be62c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif @@ -783,10 +783,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -798,20 +801,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -854,17 +861,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -879,17 +888,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -901,17 +912,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -923,17 +936,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -945,17 +960,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -967,17 +984,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -989,17 +1008,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1011,17 +1032,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1039,17 +1062,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1061,17 +1086,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1083,17 +1110,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1105,20 +1134,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1130,20 +1161,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1161,17 +1194,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1186,20 +1221,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1214,20 +1251,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1245,20 +1284,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1273,20 +1314,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1304,20 +1347,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1329,20 +1374,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1357,20 +1404,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1391,20 +1440,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1422,20 +1473,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1447,20 +1500,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1478,20 +1533,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1503,20 +1560,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1531,20 +1590,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1562,17 +1623,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1593,17 +1656,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1615,17 +1680,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1637,10 +1704,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1665,7 +1731,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif index fbe4213d4..d062bfb89 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif @@ -789,10 +789,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +807,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -832,20 +837,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -891,17 +900,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -916,17 +927,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -938,17 +951,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -960,17 +975,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -982,17 +999,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1004,17 +1023,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1026,17 +1047,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1048,17 +1071,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1076,17 +1101,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1098,17 +1125,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1120,17 +1149,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1142,20 +1173,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1173,17 +1206,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1198,20 +1233,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1226,20 +1263,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1257,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1288,20 +1329,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1313,20 +1356,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1341,20 +1386,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1375,20 +1422,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1406,20 +1455,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1431,20 +1482,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1456,20 +1509,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1484,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1662,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,10 +1710,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1671,7 +1737,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif index 9c26e0574..bfb9813c5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif @@ -789,10 +789,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -804,20 +807,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -832,20 +837,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -863,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -891,17 +900,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -916,17 +927,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -938,17 +951,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -960,17 +975,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -982,17 +999,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1004,17 +1023,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1026,17 +1047,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1048,17 +1071,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1076,17 +1101,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1098,17 +1125,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1120,17 +1149,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1142,20 +1173,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1173,17 +1206,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1198,20 +1233,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1226,20 +1263,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1257,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1288,20 +1329,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1313,20 +1356,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1341,20 +1386,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1375,20 +1422,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1406,20 +1455,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1431,20 +1482,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1456,20 +1509,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1484,20 +1539,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1509,20 +1566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1599,17 +1662,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1621,17 +1686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1643,10 +1710,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1671,7 +1737,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif index c795810c2..24cc42147 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif @@ -548,10 +548,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -563,20 +566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -591,20 +596,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -622,20 +629,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -650,17 +659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -675,17 +686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -697,17 +710,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -719,17 +734,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -741,17 +758,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -763,17 +782,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -785,17 +806,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -807,17 +830,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -835,17 +860,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +884,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -879,17 +908,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -904,20 +935,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -935,20 +968,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -960,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -994,20 +1031,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1019,20 +1058,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1047,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1072,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1100,20 +1145,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1131,10 +1178,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1179,7 +1225,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif index 819864167..422cc36ba 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif @@ -793,10 +793,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -808,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -833,20 +838,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -861,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -892,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -920,20 +931,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -948,20 +961,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -982,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1013,20 +1030,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1038,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1069,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1094,20 +1117,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1122,20 +1147,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1156,17 +1183,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1178,17 +1207,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1200,17 +1231,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1225,17 +1258,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1250,17 +1285,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1272,17 +1309,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1316,17 +1357,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1338,17 +1381,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1360,17 +1405,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1382,17 +1429,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1482,17 +1537,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1507,20 +1564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1538,20 +1597,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1563,20 +1624,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1588,20 +1651,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1616,20 +1681,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1647,10 +1714,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1675,7 +1741,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif index ed35008ef..d964961a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif @@ -785,10 +785,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -800,20 +803,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -859,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -884,17 +893,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -906,17 +917,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -928,17 +941,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -950,17 +965,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -972,17 +989,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -994,17 +1013,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1016,17 +1037,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1044,17 +1067,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1066,17 +1091,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1088,17 +1115,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1110,20 +1139,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1141,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1166,20 +1199,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1194,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1225,20 +1262,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1253,20 +1292,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1284,20 +1325,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1309,20 +1352,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1337,20 +1382,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1371,20 +1418,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1402,20 +1451,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1427,20 +1478,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1452,20 +1505,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1480,20 +1535,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1564,17 +1625,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1595,17 +1658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1617,17 +1682,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1639,10 +1706,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1667,7 +1733,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif index 2655b2e5d..b4bfdd928 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif @@ -770,10 +770,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -785,20 +788,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -810,20 +815,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -838,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -869,20 +878,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -897,20 +908,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -925,20 +938,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -959,20 +974,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -990,20 +1007,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1015,20 +1034,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1046,20 +1067,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1071,20 +1094,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1099,20 +1124,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1133,17 +1160,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1155,17 +1184,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1177,17 +1208,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1202,17 +1235,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1227,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1249,17 +1286,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1271,17 +1310,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1293,17 +1334,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1315,17 +1358,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1337,17 +1382,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1359,17 +1406,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1387,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1484,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1456,20 +1511,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1487,20 +1544,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1512,20 +1571,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1537,20 +1598,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1565,20 +1628,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1644,7 +1708,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif index 2cb1a3d62..74c363ff2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -832,20 +837,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +867,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -885,17 +894,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -907,17 +918,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -929,17 +942,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -951,17 +966,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -973,17 +990,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -995,17 +1014,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1017,17 +1038,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1045,17 +1068,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1067,17 +1092,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1089,17 +1116,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1111,20 +1140,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1142,17 +1173,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1167,20 +1200,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1195,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1226,20 +1263,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1254,20 +1293,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1285,20 +1326,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1310,20 +1353,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1338,20 +1383,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1372,20 +1419,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1403,20 +1452,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1428,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1453,20 +1506,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1481,20 +1536,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1563,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1626,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1683,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif index 671bb1a69..ced2de24f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -832,20 +837,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -860,17 +867,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -885,17 +894,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -907,17 +918,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -929,17 +942,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -951,17 +966,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -973,17 +990,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -995,17 +1014,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1017,17 +1038,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1045,17 +1068,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1067,17 +1092,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1089,17 +1116,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1111,20 +1140,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1142,17 +1173,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1167,20 +1200,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1195,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1226,20 +1263,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1254,20 +1293,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1285,20 +1326,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1310,20 +1353,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1338,20 +1383,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1372,20 +1419,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1403,20 +1452,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1428,20 +1479,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1453,20 +1506,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1481,20 +1536,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1506,20 +1563,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1534,20 +1593,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1565,17 +1626,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1596,17 +1659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1618,17 +1683,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif index 21276b14c..7f165a3e4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif @@ -546,10 +546,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -561,20 +564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -592,20 +597,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -620,17 +627,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -645,17 +654,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -667,17 +678,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -689,17 +702,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -711,17 +726,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -733,17 +750,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -755,17 +774,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -777,17 +798,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -805,17 +828,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -827,17 +852,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -849,17 +876,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -874,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -902,20 +933,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -933,20 +966,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -958,20 +993,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -992,20 +1029,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1017,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1045,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1070,20 +1113,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1098,20 +1143,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1129,10 +1176,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1177,7 +1223,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif index 63cff34d6..f4ecb2572 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif @@ -785,10 +785,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -800,20 +803,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -859,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -884,17 +893,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -906,17 +917,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -928,17 +941,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -950,17 +965,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -972,17 +989,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -994,17 +1013,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1016,17 +1037,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1044,17 +1067,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1066,17 +1091,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1088,17 +1115,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1110,20 +1139,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1141,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1166,20 +1199,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1194,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1225,20 +1262,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1253,20 +1292,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1284,20 +1325,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1309,20 +1352,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1337,20 +1382,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1371,20 +1418,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1402,20 +1451,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1427,20 +1478,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1452,20 +1505,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1480,20 +1535,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1564,17 +1625,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1595,17 +1658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1617,17 +1682,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1639,10 +1706,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1667,7 +1733,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif index 848b1e3b0..68ef9a93e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif @@ -796,10 +796,13 @@ "rules": [ { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -817,20 +820,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -842,20 +847,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -870,20 +877,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -904,17 +913,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -926,17 +937,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -948,17 +961,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -973,17 +988,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -998,17 +1015,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1020,17 +1039,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1042,17 +1063,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1064,17 +1087,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1086,17 +1111,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1108,17 +1135,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1130,17 +1159,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1158,17 +1189,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1180,17 +1213,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1202,17 +1237,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1224,20 +1261,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1249,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1280,17 +1321,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1305,20 +1348,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1333,20 +1378,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1364,20 +1411,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1392,20 +1441,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1423,20 +1474,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1448,20 +1501,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1476,20 +1531,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1510,20 +1567,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1541,20 +1600,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1566,20 +1627,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1591,20 +1654,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1619,20 +1684,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1650,10 +1717,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1678,7 +1744,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif index 8df82d0c4..d86c3a995 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif @@ -624,10 +624,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -639,20 +642,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -667,20 +672,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -695,20 +702,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -729,20 +738,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -760,20 +771,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -785,20 +798,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -816,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -844,20 +861,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -872,17 +891,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -897,17 +918,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -919,17 +942,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -941,17 +966,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -963,17 +990,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -985,17 +1014,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1007,17 +1038,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1029,17 +1062,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1057,17 +1092,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1079,17 +1116,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1101,17 +1140,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1126,20 +1167,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1200,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1182,20 +1227,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1207,20 +1254,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1281,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1311,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,10 +1344,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1339,7 +1391,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif index 80e240961..2bdc140b4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif @@ -550,10 +550,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -565,20 +568,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -593,20 +598,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -624,20 +631,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -652,20 +661,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -680,17 +691,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -705,17 +718,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -727,17 +742,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -749,17 +766,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -771,17 +790,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -793,17 +814,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -815,17 +838,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -837,17 +862,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -865,17 +892,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -887,17 +916,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -909,17 +940,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -934,20 +967,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -965,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -990,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1024,20 +1063,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1049,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1074,20 +1117,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1102,20 +1147,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1133,10 +1180,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1181,7 +1227,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif index 2657e9c08..a9363ccc4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +835,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -858,20 +865,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -889,20 +898,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -917,20 +928,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -942,20 +955,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -970,20 +985,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1004,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1035,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1060,20 +1081,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1091,20 +1114,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1119,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1153,17 +1180,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1175,17 +1204,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1197,17 +1228,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1222,17 +1255,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1247,17 +1282,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1269,17 +1306,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1313,17 +1354,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1335,17 +1378,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1357,17 +1402,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1379,17 +1426,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1407,17 +1456,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1429,17 +1480,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1451,17 +1504,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1504,20 +1561,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1535,20 +1594,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1560,20 +1621,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1585,20 +1648,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1613,20 +1678,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif index 7b49280a7..f460a1e68 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -856,20 +863,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -887,20 +896,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -915,20 +926,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -940,20 +953,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -968,20 +983,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1033,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1089,20 +1112,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1123,17 +1148,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1145,17 +1172,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1167,17 +1196,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1192,17 +1223,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1217,17 +1250,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1239,17 +1274,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1261,17 +1298,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1283,17 +1322,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1305,17 +1346,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1327,17 +1370,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1349,17 +1394,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1377,17 +1424,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1399,17 +1448,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1421,17 +1472,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1449,17 +1502,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1474,20 +1529,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif index 952b46338..2a95faac1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif @@ -624,10 +624,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -642,20 +645,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -670,20 +675,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -704,20 +711,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -735,20 +744,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -760,20 +771,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -791,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -816,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -844,20 +861,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -872,17 +891,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -897,17 +918,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -919,17 +942,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -941,17 +966,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -963,17 +990,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -985,17 +1014,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1007,17 +1038,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1029,17 +1062,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1057,17 +1092,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1079,17 +1116,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1101,17 +1140,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1123,20 +1164,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1151,20 +1194,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1182,20 +1227,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1207,20 +1254,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1281,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1311,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,10 +1344,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1339,7 +1391,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif index 69ddf6274..f50bbe73a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif @@ -548,10 +548,13 @@ "rules": [ { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -566,20 +569,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -591,20 +596,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -619,20 +626,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -647,17 +656,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -672,17 +683,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -694,17 +707,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -716,17 +731,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -738,17 +755,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -760,17 +779,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -782,17 +803,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -804,17 +827,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -832,17 +857,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -854,17 +881,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -876,17 +905,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -898,20 +929,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -926,20 +959,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -957,20 +992,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -982,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1016,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1047,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1072,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1100,20 +1145,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1131,10 +1178,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1179,7 +1225,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif index ed2e8e1e3..f4d8de87c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif @@ -794,10 +794,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -840,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -874,17 +881,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -896,17 +905,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -918,17 +929,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -943,17 +956,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -968,17 +983,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -990,17 +1007,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1012,17 +1031,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1034,17 +1055,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1056,17 +1079,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1078,17 +1103,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1100,17 +1127,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1128,17 +1157,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1150,17 +1181,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1172,17 +1205,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1194,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1225,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1250,20 +1289,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1278,20 +1319,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1309,20 +1352,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1337,20 +1382,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1368,20 +1415,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1393,20 +1442,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1421,20 +1472,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1455,20 +1508,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1486,20 +1541,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1511,20 +1568,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1595,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1625,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1652,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1682,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,10 +1715,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1676,7 +1742,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif index a8fb7089c..2ab54d3e3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif @@ -794,10 +794,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -809,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -837,20 +842,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -871,17 +878,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -893,17 +902,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -915,17 +926,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -940,17 +953,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -965,17 +980,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -987,17 +1004,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1009,17 +1028,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1031,17 +1052,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1053,17 +1076,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1075,17 +1100,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1097,17 +1124,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1125,17 +1154,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1147,17 +1178,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1169,17 +1202,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1191,20 +1226,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1216,20 +1253,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1247,17 +1286,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1272,20 +1313,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1300,20 +1343,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1331,20 +1376,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1359,20 +1406,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1390,20 +1439,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1415,20 +1466,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1443,20 +1496,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1477,20 +1532,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1508,20 +1565,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1533,20 +1592,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1564,20 +1625,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1652,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1682,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,10 +1715,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1676,7 +1742,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif index 36a857b6b..ac694af16 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif @@ -622,10 +622,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -637,20 +640,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -665,20 +670,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -693,20 +700,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -727,20 +736,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -758,20 +769,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -783,20 +796,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -814,20 +829,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -842,17 +859,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -867,17 +886,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -889,17 +910,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -911,17 +934,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -933,17 +958,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -955,17 +982,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -977,17 +1006,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -999,17 +1030,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1027,17 +1060,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1049,17 +1084,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1071,17 +1108,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1096,20 +1135,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1127,20 +1168,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1152,20 +1195,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1177,20 +1222,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1205,20 +1252,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1230,20 +1279,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1258,20 +1309,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1289,10 +1342,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1337,7 +1389,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif index 9c85f2193..10468401e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif @@ -548,10 +548,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -563,20 +566,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -591,20 +596,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -622,20 +629,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -650,17 +659,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -675,17 +686,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -697,17 +710,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -719,17 +734,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -741,17 +758,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -763,17 +782,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -785,17 +806,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -807,17 +830,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -835,17 +860,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -857,17 +884,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -879,17 +908,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -904,20 +935,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -935,20 +968,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -960,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -994,20 +1031,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1019,20 +1058,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1047,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1072,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1100,20 +1145,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1131,10 +1178,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1179,7 +1225,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif index f78ae0aa5..8201480c5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif @@ -794,10 +794,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -809,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -840,20 +845,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -874,17 +881,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -896,17 +905,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -918,17 +929,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -943,17 +956,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -968,17 +983,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -990,17 +1007,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1012,17 +1031,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1034,17 +1055,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1056,17 +1079,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1078,17 +1103,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1100,17 +1127,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1128,17 +1157,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1150,17 +1181,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1172,17 +1205,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1194,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1225,17 +1262,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1250,20 +1289,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1278,20 +1319,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1309,20 +1352,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1337,20 +1382,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1368,20 +1415,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1393,20 +1442,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1421,20 +1472,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1455,20 +1508,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1486,20 +1541,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1511,20 +1568,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1536,20 +1595,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1564,20 +1625,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1589,20 +1652,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1617,20 +1682,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1648,10 +1715,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1676,7 +1742,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif index 53a852bdd..03b323971 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif @@ -788,10 +788,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -803,20 +806,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -828,20 +833,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -859,17 +866,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -884,20 +893,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -915,20 +926,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -943,20 +956,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -971,20 +986,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1002,20 +1019,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1027,20 +1046,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1092,17 +1115,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1114,17 +1139,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1136,17 +1163,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1161,17 +1190,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1186,17 +1217,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1208,17 +1241,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1230,17 +1265,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1252,17 +1289,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1274,17 +1313,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1296,17 +1337,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1318,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1346,17 +1391,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1368,17 +1415,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1390,17 +1439,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1415,20 +1466,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1446,20 +1499,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1471,20 +1526,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1505,20 +1562,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1530,20 +1589,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1558,20 +1619,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1583,20 +1646,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1611,20 +1676,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1642,10 +1709,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1670,7 +1736,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif index 1efe8af75..572a4f33e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif index 4dace2bce..cdbd59af4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif @@ -790,10 +790,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -805,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -830,20 +835,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -861,17 +868,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -886,20 +895,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -914,20 +925,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -945,20 +958,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -973,20 +988,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1004,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1029,20 +1048,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1057,20 +1078,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1091,20 +1114,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1122,20 +1147,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1147,20 +1174,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1178,20 +1207,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1203,20 +1234,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1231,20 +1264,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1256,20 +1291,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1284,20 +1321,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1315,17 +1354,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1346,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1368,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1390,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1412,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1434,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1462,17 +1513,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1484,17 +1537,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1506,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1531,17 +1588,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1556,17 +1615,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1578,17 +1639,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1600,17 +1663,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1622,17 +1687,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1644,10 +1711,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1672,7 +1738,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif index 2106596f9..c6c2dd4c7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1438,17 +1489,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1460,17 +1513,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1482,17 +1537,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1507,17 +1564,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1532,17 +1591,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1554,17 +1615,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1576,17 +1639,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif index 9ad06775e..ced8d21a8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif @@ -767,10 +767,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -782,20 +785,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -807,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -838,17 +845,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -863,20 +872,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -891,20 +902,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -922,20 +935,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -950,20 +965,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -981,20 +998,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1006,20 +1025,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1034,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1068,20 +1091,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1099,20 +1124,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1124,20 +1151,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1155,20 +1184,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1211,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1241,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1268,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1298,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,17 +1331,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1323,17 +1364,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1345,17 +1388,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1367,17 +1412,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1389,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1411,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1439,17 +1490,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1461,17 +1514,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1483,17 +1538,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1508,17 +1565,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1533,17 +1592,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1555,17 +1616,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1577,17 +1640,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1599,10 +1664,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1627,7 +1691,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif index f97b4d9b7..71ea0b041 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif @@ -769,10 +769,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +787,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +814,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +847,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +874,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +904,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +967,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1093,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1126,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1186,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1213,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1243,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1270,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1300,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1366,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1390,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1414,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1438,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1462,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1492,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1516,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1540,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1567,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1594,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1618,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1642,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,10 +1666,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1629,7 +1693,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif index 3932661a6..37f9d23aa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif index 8cd3417e8..55fb931a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif index 2bf4e51a2..5c58272b9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif index fed7f4958..e2c05f952 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif @@ -769,10 +769,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +787,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +814,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +847,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +874,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +904,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +967,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1093,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1126,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1186,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1213,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1243,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1270,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1300,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1366,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1390,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1414,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1438,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1462,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1492,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1516,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1540,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1567,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1594,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1618,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1642,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,10 +1666,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1629,7 +1693,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif index ad3165422..6a78d0a88 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif index eb72b4850..d5ff61efa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif @@ -780,10 +780,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -795,20 +798,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -820,20 +825,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -851,17 +858,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -876,20 +885,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -904,20 +915,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -935,20 +948,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -963,20 +978,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -994,20 +1011,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1019,20 +1038,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1047,20 +1068,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1081,20 +1104,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1112,20 +1137,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1137,20 +1164,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1168,20 +1197,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1193,20 +1224,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1221,20 +1254,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1246,20 +1281,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1274,20 +1311,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1305,17 +1344,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1336,17 +1377,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1358,17 +1401,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1380,17 +1425,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1430,17 +1479,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1452,17 +1503,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1474,17 +1527,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1496,17 +1551,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1518,17 +1575,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1540,17 +1599,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1590,17 +1653,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1612,10 +1677,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null } ], "properties": { @@ -1640,7 +1704,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif index 62c28fec1..cd0f0024b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif @@ -769,10 +769,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +787,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +814,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +847,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +874,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +904,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +967,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1093,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1126,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1186,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1213,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1243,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1270,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1300,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1366,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1390,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1414,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1438,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1462,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1492,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1516,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1540,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1567,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1594,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1618,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1642,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,10 +1666,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1629,7 +1693,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif index d8cf9c904..615a3ae24 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif index 00a2a57b7..eb99839b5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif @@ -767,10 +767,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -782,20 +785,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -807,20 +812,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -838,17 +845,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -863,20 +872,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -891,20 +902,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -922,20 +935,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -950,20 +965,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -981,20 +998,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1006,20 +1025,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1034,20 +1055,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1068,20 +1091,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1099,20 +1124,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1124,20 +1151,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1155,20 +1184,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1180,20 +1211,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1208,20 +1241,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1233,20 +1268,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1261,20 +1298,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1292,17 +1331,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1323,17 +1364,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1345,17 +1388,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1367,17 +1412,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1389,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1411,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1439,17 +1490,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1461,17 +1514,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1483,17 +1538,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1508,17 +1565,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1533,17 +1592,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1555,17 +1616,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1577,17 +1640,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1599,10 +1664,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1627,7 +1691,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif index 55e6791e6..c80e665bb 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif @@ -769,10 +769,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +787,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +814,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +847,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +874,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +904,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +967,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1093,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1126,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1186,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1213,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1243,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1270,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1300,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1366,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1390,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1414,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1438,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1462,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1492,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1516,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1540,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1567,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1594,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1618,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1642,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,10 +1666,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1629,7 +1693,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif index f89139875..ef272b59e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.a.sarif @@ -50,7 +50,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif index 578b66b28..5f491d2c5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1440,17 +1491,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1462,17 +1515,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1484,17 +1539,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1509,17 +1566,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1534,17 +1593,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1556,17 +1617,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1578,17 +1641,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif index 6e851b19b..16c236d2c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif @@ -769,10 +769,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -784,20 +787,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -809,20 +814,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -840,17 +847,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -865,20 +874,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -893,20 +904,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -924,20 +937,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -952,20 +967,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -983,20 +1000,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1008,20 +1027,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1036,20 +1057,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1070,20 +1093,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1101,20 +1126,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1126,20 +1153,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1157,20 +1186,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1182,20 +1213,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1210,20 +1243,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1235,20 +1270,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1263,20 +1300,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1294,17 +1333,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1325,17 +1366,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1347,17 +1390,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1369,17 +1414,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1391,17 +1438,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1413,17 +1462,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1441,17 +1492,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1463,17 +1516,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1485,17 +1540,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1510,17 +1567,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1535,17 +1594,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1557,17 +1618,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1579,17 +1642,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1601,10 +1666,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null } ], "properties": { @@ -1629,7 +1693,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif index 5b0b10f0a..bf1a95853 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif @@ -783,10 +783,13 @@ "rules": [ { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -798,20 +801,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -854,17 +861,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -879,17 +888,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -901,17 +912,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -923,17 +936,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -945,17 +960,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -967,17 +984,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -989,17 +1008,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1011,17 +1032,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1039,17 +1062,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1061,17 +1086,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1083,17 +1110,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -1105,20 +1134,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -1130,20 +1161,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -1161,17 +1194,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -1186,20 +1221,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -1214,20 +1251,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -1245,20 +1284,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -1273,20 +1314,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1304,20 +1347,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1329,20 +1374,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1357,20 +1404,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1391,20 +1440,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1422,20 +1473,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1447,20 +1500,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1478,20 +1533,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1503,20 +1560,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1531,20 +1590,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1562,17 +1623,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1593,17 +1656,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1615,17 +1680,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1637,10 +1704,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null } ], "properties": { @@ -1665,7 +1731,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif index 1d40f5b78..0c4a9e366 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif index e9da98295..1e92efe4e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -857,17 +864,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -882,20 +891,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -910,20 +921,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -941,20 +954,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -969,20 +984,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1000,20 +1017,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1025,20 +1044,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1053,20 +1074,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1087,20 +1110,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1118,20 +1143,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1143,20 +1170,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1174,20 +1203,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1199,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1227,20 +1260,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1252,20 +1287,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1280,20 +1317,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1311,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1342,17 +1383,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1364,17 +1407,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1386,17 +1431,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1408,17 +1455,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1430,17 +1479,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1455,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1480,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1502,17 +1557,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1524,17 +1581,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1546,17 +1605,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1590,17 +1653,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1612,17 +1677,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif index a1e549e32..98d22b0ab 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif @@ -763,10 +763,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -778,20 +781,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -803,20 +808,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -834,17 +841,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -859,20 +868,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -887,20 +898,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -918,20 +931,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -946,20 +961,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -977,20 +994,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1002,20 +1021,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1030,20 +1051,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1064,20 +1087,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1095,20 +1120,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1120,20 +1147,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1151,20 +1180,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1176,20 +1207,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1204,20 +1237,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1229,20 +1264,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1257,20 +1294,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1288,17 +1327,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1319,17 +1360,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1341,17 +1384,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1363,17 +1408,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1385,17 +1432,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1407,17 +1456,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1429,17 +1480,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1451,17 +1504,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1476,17 +1531,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1501,17 +1558,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1523,17 +1582,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1545,17 +1606,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1567,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1595,10 +1660,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1623,7 +1687,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif index ab9c258f9..bff84f6ea 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif @@ -764,10 +764,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -779,20 +782,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -804,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -835,17 +842,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -860,20 +869,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -888,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -919,20 +932,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -947,20 +962,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -978,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1003,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1031,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1065,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1096,20 +1121,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1121,20 +1148,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1152,20 +1181,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1177,20 +1208,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1205,20 +1238,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1230,20 +1265,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1258,20 +1295,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1289,17 +1328,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1320,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1342,17 +1385,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1364,17 +1409,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1386,17 +1433,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1408,17 +1457,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1430,17 +1481,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1477,17 +1532,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1502,17 +1559,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1524,17 +1583,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1546,17 +1607,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1568,17 +1631,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1624,7 +1688,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif index 81fd266b3..e5b18e2dc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif index 3ff12dfa9..b9025e7e8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif @@ -804,10 +804,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -819,20 +822,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -844,20 +849,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -875,17 +882,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -900,20 +909,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -928,20 +939,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -959,20 +972,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -987,20 +1002,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1018,20 +1035,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1043,20 +1062,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1071,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1105,20 +1128,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1136,20 +1161,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1161,20 +1188,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1192,20 +1221,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1217,20 +1248,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1245,20 +1278,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1270,20 +1305,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1298,20 +1335,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1329,17 +1368,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1360,17 +1401,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1382,17 +1425,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1404,17 +1449,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1429,17 +1476,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1454,17 +1503,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1476,17 +1527,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1498,17 +1551,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1520,17 +1575,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1542,17 +1599,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1564,17 +1623,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1586,17 +1647,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1614,17 +1677,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1636,17 +1701,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1658,10 +1725,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null } ], "properties": { @@ -1686,7 +1752,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif index 11b0ddfd4..dc0daf762 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif @@ -791,10 +791,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -806,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -831,20 +836,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -862,17 +869,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -887,20 +896,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -915,20 +926,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -946,20 +959,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -974,20 +989,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1005,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1030,20 +1049,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1058,20 +1079,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1092,20 +1115,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1123,20 +1148,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1148,20 +1175,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1179,20 +1208,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1204,20 +1235,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1232,20 +1265,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1257,20 +1292,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1285,20 +1322,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1316,17 +1355,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1347,17 +1388,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1369,17 +1412,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1391,17 +1436,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1413,17 +1460,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1435,17 +1484,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1457,17 +1508,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1479,17 +1532,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1504,17 +1559,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1529,17 +1586,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1551,17 +1610,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1573,17 +1634,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1595,17 +1658,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1617,17 +1682,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1645,10 +1712,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1673,7 +1739,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif index 936dfd938..21d092754 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -857,17 +864,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -882,20 +891,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -910,20 +921,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -941,20 +954,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -969,20 +984,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1000,20 +1017,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1025,20 +1044,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1053,20 +1074,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1087,20 +1110,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1118,20 +1143,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1143,20 +1170,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1174,20 +1203,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1199,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1227,20 +1260,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1252,20 +1287,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1280,20 +1317,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1311,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1342,17 +1383,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1364,17 +1407,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1386,17 +1431,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1408,17 +1455,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1430,17 +1479,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1455,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1480,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1502,17 +1557,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1524,17 +1581,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1546,17 +1605,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1590,17 +1653,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1612,17 +1677,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif index 18a6fcf49..459c7a484 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -802,20 +805,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -827,20 +832,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -858,17 +865,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -883,20 +892,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -911,20 +922,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -942,20 +955,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -970,20 +985,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1001,20 +1018,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1026,20 +1045,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1054,20 +1075,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1088,20 +1111,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1119,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1144,20 +1171,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1175,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1200,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1228,20 +1261,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1253,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1281,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1312,17 +1351,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1343,17 +1384,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1365,17 +1408,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1387,17 +1432,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1456,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1480,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1456,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1481,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1503,17 +1558,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1525,17 +1582,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1547,17 +1606,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1591,17 +1654,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1613,17 +1678,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif index c5fff30d4..71d6188ac 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif @@ -785,10 +785,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -800,20 +803,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -825,20 +830,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -856,17 +863,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -881,20 +890,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -909,20 +920,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -940,20 +953,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -968,20 +983,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -999,20 +1016,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1024,20 +1043,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1052,20 +1073,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1086,20 +1109,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1117,20 +1142,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1142,20 +1169,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1173,20 +1202,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1198,20 +1229,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1226,20 +1259,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1251,20 +1286,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1279,20 +1316,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1310,17 +1349,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1341,17 +1382,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1363,17 +1406,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1385,17 +1430,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1407,17 +1454,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1429,17 +1478,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1454,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1479,17 +1532,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1501,17 +1556,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1523,17 +1580,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1545,17 +1604,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1567,17 +1628,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1589,17 +1652,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1611,17 +1676,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1639,10 +1706,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1667,7 +1733,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif index 8513c526d..a1af4303f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif @@ -768,10 +768,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -783,20 +786,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -808,20 +813,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -839,17 +846,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -864,20 +873,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -892,20 +903,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -923,20 +936,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -951,20 +966,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -982,20 +999,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1007,20 +1026,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1035,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1069,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1100,20 +1125,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1125,20 +1152,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1156,20 +1185,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1181,20 +1212,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1209,20 +1242,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1234,20 +1269,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1262,20 +1299,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1293,17 +1332,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1324,17 +1365,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1346,17 +1389,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1368,17 +1413,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1390,17 +1437,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1412,17 +1461,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1434,17 +1485,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1456,17 +1509,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1481,17 +1536,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1506,17 +1563,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1528,17 +1587,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1550,17 +1611,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1572,17 +1635,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1600,10 +1665,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1628,7 +1692,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif index 2592d3ea2..3c828b129 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -802,20 +805,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -827,20 +832,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -858,17 +865,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -883,20 +892,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -911,20 +922,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -942,20 +955,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -970,20 +985,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1001,20 +1018,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1026,20 +1045,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1054,20 +1075,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1088,20 +1111,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1119,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1144,20 +1171,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1175,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1200,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1228,20 +1261,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1253,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1281,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1312,17 +1351,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1343,17 +1384,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1365,17 +1408,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1387,17 +1432,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1456,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1480,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1456,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1481,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1503,17 +1558,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1525,17 +1582,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1547,17 +1606,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1591,17 +1654,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1613,17 +1678,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif index 1b13fc73c..aa06601e2 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif index aed6007fa..ec7218504 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif index d06cc2060..00169bfdc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif index 572620b5d..76e30e0e0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif index 18041a37d..26a2ec96b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif index a77beb456..db5a7a2ee 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif index 2f262ac72..70aa2d308 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif index f85e732f4..a352562a4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif @@ -804,10 +804,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -819,20 +822,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -844,20 +849,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -875,17 +882,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -900,20 +909,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -928,20 +939,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -959,20 +972,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -987,20 +1002,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1018,20 +1035,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1043,20 +1062,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1071,20 +1092,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1105,20 +1128,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1136,20 +1161,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1161,20 +1188,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1192,20 +1221,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1217,20 +1248,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1245,20 +1278,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1270,20 +1305,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1298,20 +1335,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1329,17 +1368,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1360,17 +1401,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1382,17 +1425,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1404,17 +1449,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1429,17 +1476,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1454,17 +1503,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1476,17 +1527,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1498,17 +1551,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1520,17 +1575,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1542,17 +1599,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1564,17 +1623,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1586,17 +1647,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1614,17 +1677,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1636,17 +1701,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1658,10 +1725,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null } ], "properties": { @@ -1686,7 +1752,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif index ad4101d3d..cafef0877 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif @@ -764,10 +764,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -779,20 +782,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -804,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -835,17 +842,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -860,20 +869,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -888,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -919,20 +932,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -947,20 +962,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -978,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1003,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1031,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1065,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1096,20 +1121,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1121,20 +1148,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1152,20 +1181,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1177,20 +1208,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1205,20 +1238,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1230,20 +1265,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1258,20 +1295,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1289,17 +1328,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1320,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1342,17 +1385,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1364,17 +1409,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1386,17 +1433,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1408,17 +1457,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1433,17 +1484,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1458,17 +1511,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1480,17 +1535,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1502,17 +1559,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1524,17 +1583,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1546,17 +1607,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1568,17 +1631,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1624,7 +1688,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif index 283ccc4c2..1b735753c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif @@ -780,10 +780,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -795,20 +798,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -820,20 +825,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -851,17 +858,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -876,20 +885,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -904,20 +915,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -935,20 +948,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -963,20 +978,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -994,20 +1011,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1019,20 +1038,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1047,20 +1068,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1081,20 +1104,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1112,20 +1137,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1137,20 +1164,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1168,20 +1197,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1193,20 +1224,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1221,20 +1254,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1246,20 +1281,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1274,20 +1311,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1305,17 +1344,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1336,17 +1377,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1358,17 +1401,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1380,17 +1425,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1405,17 +1452,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1430,17 +1479,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1452,17 +1503,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1474,17 +1527,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1496,17 +1551,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1518,17 +1575,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1540,17 +1599,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1590,17 +1653,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1612,10 +1677,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null } ], "properties": { @@ -1640,7 +1704,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif index 336295499..73b08fdae 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif @@ -546,10 +546,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -561,20 +564,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -589,20 +594,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -620,20 +627,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -648,17 +657,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -673,17 +684,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -695,17 +708,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -717,17 +732,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -739,17 +756,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -761,17 +780,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -783,17 +804,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -805,17 +828,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -833,17 +858,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -855,17 +882,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -877,17 +906,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -902,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -933,20 +966,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -958,20 +993,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -992,20 +1029,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1017,20 +1056,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1045,20 +1086,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1070,20 +1113,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1098,20 +1143,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1129,10 +1176,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null } ], "properties": { @@ -1177,7 +1223,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif index 2262b817b..9d2d81f2c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif index f1c44447a..198bdb5ab 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif index 5fbb05e12..b3496781a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif @@ -764,10 +764,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -779,20 +782,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -804,20 +809,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -835,17 +842,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -860,20 +869,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -888,20 +899,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -919,20 +932,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -947,20 +962,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -978,20 +995,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1003,20 +1022,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1031,20 +1052,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1065,20 +1088,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1096,20 +1121,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1121,20 +1148,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1152,20 +1181,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1177,20 +1208,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1205,20 +1238,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1230,20 +1265,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1258,20 +1295,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1289,17 +1328,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1320,17 +1361,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1342,17 +1385,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1364,17 +1409,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1386,17 +1433,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1408,17 +1457,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1430,17 +1481,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1452,17 +1505,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1477,17 +1532,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1502,17 +1559,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1524,17 +1583,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1546,17 +1607,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1568,17 +1631,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1596,10 +1661,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1624,7 +1688,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif index 312145eac..931a64434 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif @@ -786,10 +786,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -801,20 +804,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -826,20 +831,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -857,17 +864,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -882,20 +891,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -910,20 +921,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -941,20 +954,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -969,20 +984,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1000,20 +1017,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1025,20 +1044,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1053,20 +1074,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1087,20 +1110,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1118,20 +1143,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1143,20 +1170,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1174,20 +1203,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1199,20 +1230,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1227,20 +1260,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1252,20 +1287,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1280,20 +1317,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1311,17 +1350,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1342,17 +1383,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1364,17 +1407,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1386,17 +1431,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1408,17 +1455,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1430,17 +1479,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1455,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1480,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1502,17 +1557,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1524,17 +1581,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1546,17 +1605,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1568,17 +1629,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1590,17 +1653,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1612,17 +1677,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1640,10 +1707,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1668,7 +1734,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif index 843601633..075b1de8a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif @@ -787,10 +787,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -802,20 +805,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -827,20 +832,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -858,17 +865,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -883,20 +892,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -911,20 +922,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -942,20 +955,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -970,20 +985,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -1001,20 +1018,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1026,20 +1045,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1054,20 +1075,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1088,20 +1111,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1119,20 +1144,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1144,20 +1171,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1175,20 +1204,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1200,20 +1231,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1228,20 +1261,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1253,20 +1288,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1281,20 +1318,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1312,17 +1351,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1343,17 +1384,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1365,17 +1408,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1387,17 +1432,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1409,17 +1456,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1431,17 +1480,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1456,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1481,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1503,17 +1558,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3004", - "name": "GenerateRequiredSymbolFormat", "fullDescription": { "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", + "help": { + "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." + }, "messageStrings": { "Pass": { "text": "The version of the debugging dwarf format is '{0}' for the file '{1}'" @@ -1525,17 +1582,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3004GenerateRequiredSymbolFormat", - "help": { - "text": "This check ensures that debugging dwarf version used is 5. The dwarf version 5 contains more information and should be used. Use the compiler flags '-gdwarf-5' to enable this." - } + "shortDescription": null, + "name": "GenerateRequiredSymbolFormat", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1547,17 +1606,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1569,17 +1630,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1591,17 +1654,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1613,17 +1678,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1641,10 +1708,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1669,7 +1735,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif index 87314dd22..f88dafd66 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif index a5ab148a0..989407353 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.a.sarif @@ -50,7 +50,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif index e498ed1b9..18e78bdcc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif index c0fa83431..c931c9ad0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif @@ -766,10 +766,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -781,20 +784,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -806,20 +811,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -837,17 +844,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -862,20 +871,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -890,20 +901,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -921,20 +934,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -949,20 +964,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -980,20 +997,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1005,20 +1024,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1033,20 +1054,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1067,20 +1090,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1098,20 +1123,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1123,20 +1150,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1154,20 +1183,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1179,20 +1210,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1207,20 +1240,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1232,20 +1267,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1260,20 +1297,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1291,17 +1330,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1322,17 +1363,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1344,17 +1387,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1366,17 +1411,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1388,17 +1435,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1410,17 +1459,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1432,17 +1483,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1454,17 +1507,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1479,17 +1534,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1504,17 +1561,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1526,17 +1585,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1548,17 +1609,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1570,17 +1633,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1598,10 +1663,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1626,7 +1690,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif index 9c7fc0650..85b8b4821 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif @@ -765,10 +765,13 @@ "rules": [ { "id": "BA2001", - "name": "LoadImageAboveFourGigabyteAddress", "fullDescription": { "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", + "help": { + "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." + }, "messageStrings": { "Pass": { "text": "'{0}' is a 64-bit image with a base address that is >= 4 gigabytes, increasing the effectiveness of Address Space Layout Randomization (which helps prevent attackers from executing security-sensitive code in well-known locations)." @@ -780,20 +783,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2001LoadImageAboveFourGigabyteAddress", - "help": { - "text": "64-bit images should have a preferred base address above the 4GB boundary to prevent triggering an Address Space Layout Randomization (ASLR) compatibility mode that decreases security. ASLR compatibility mode reduces the number of locations to which ASLR may relocate the binary, reducing its effectiveness at mitigating memory corruption vulnerabilities. To resolve this issue, either use the default preferred base address by removing any uses of /baseaddress from compiler command lines, or /BASE from linker command lines (recommended), or configure your program to start at a base address above 4GB when compiled for 64 bit platforms (by changing the constant passed to /baseaddress or /BASE). Note that if you choose to continue using a custom preferred base address, you will need to make this modification only for 64-bit builds, as base addresses above 4GB are not valid for 32-bit binaries." - }, + "shortDescription": null, + "name": "LoadImageAboveFourGigabyteAddress", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } }, { "id": "BA2002", - "name": "DoNotIncorporateVulnerableDependencies", "fullDescription": { "text": "Binaries should not take dependencies on code with known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", + "help": { + "text": "Binaries should not take dependencies on code with known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' does not incorporate any known vulnerable dependencies, as configured by current policy." @@ -805,20 +810,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2002DoNotIncorporateVulnerableDependencies", - "help": { - "text": "Binaries should not take dependencies on code with known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotIncorporateVulnerableDependencies", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } }, { "id": "BA2004", - "name": "EnableSecureSourceCodeHashing", "fullDescription": { "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", + "help": { + "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." + }, "messageStrings": { "Pass": { "text": "'{0}' is a {1} binary which was compiled with a secure (SHA-256) source code hashing algorithm." @@ -836,17 +843,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2004EnableSecureSourceCodeHashing", - "help": { - "text": "Compilers can generate and store checksums of source files in order to provide linkage between binaries, their PDBs, and associated source code. This information is typically used to resolve source file when debugging but it can also be used to verify that a specific body of source code is, in fact, the code that was used to produce a specific set of binaries and PDBs. This validation is helpful in verifying supply chain integrity. Due to this security focus, it is important that the hashing algorithm used to produce checksums is secure. Legacy hashing algorithms, such as MD5 and SHA-1, have been demonstrated to be broken by modern hardware (that is, it is computationally feasible to force hash collisions, in which a common hash is generated from distinct files). Using a secure hashing algorithm, such as SHA-256, prevents the possibility of collision attacks, in which the checksum of a malicious file is used to produce a hash that satisfies the system that it is, in fact, the original file processed by the compiler. For managed binaries, pass '-checksumalgorithm:SHA256' on the csc.exe command-line or populate the '' project property with 'SHA256' to enable secure source code hashing. For native binaries, pass '/ZH:SHA_256' on the cl.exe command-line to enable secure source code hashing." - } + "shortDescription": null, + "name": "EnableSecureSourceCodeHashing", + "guid": null }, { "id": "BA2005", - "name": "DoNotShipVulnerableBinaries", "fullDescription": { "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", + "help": { + "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." + }, "messageStrings": { "Pass": { "text": "'{0}' is not known to be an obsolete binary that is vulnerable to one or more security problems." @@ -861,20 +870,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2005DoNotShipVulnerableBinaries", - "help": { - "text": "Do not ship obsolete libraries for which there are known security vulnerabilities." - }, + "shortDescription": null, + "name": "DoNotShipVulnerableBinaries", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } }, { "id": "BA2006", - "name": "BuildWithSecureTools", "fullDescription": { "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", + "help": { + "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." + }, "messageStrings": { "Error": { "text": "'{0}' was compiled with one or more modules which were not built using minimum required tool versions (compiler version {1}). More recent toolchains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning. Modules built outside of policy: \r\n{2}" @@ -889,20 +900,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2006BuildWithSecureTools", - "help": { - "text": "Application code should be compiled with the most up-to-date tool sets possible to take advantage of the most current compile-time security features. Among other things, these features provide address space layout randomization, help prevent arbitrary code execution, and enable code generation that can help prevent speculative execution side-channel attacks." - }, + "shortDescription": null, + "name": "BuildWithSecureTools", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } }, { "id": "BA2007", - "name": "EnableCriticalCompilerWarnings", "fullDescription": { "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", + "help": { + "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." + }, "messageStrings": { "Pass": { "text": "'{0}' was compiled at a secure warning level ({1}) and does not include any modules that disable specific warnings that are required by policy. As a result, it is less likely that memory corruption, information disclosure, double-free and other security-related vulnerabilities exist in code." @@ -920,20 +933,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2007EnableCriticalCompilerWarnings", - "help": { - "text": "Binaries should be compiled with a warning level that enables all critical security-relevant checks. Enabling at least warning level 3 enables important static analysis in the compiler that can identify bugs with a potential to provoke memory corruption, information disclosure, or double-free vulnerabilities. To resolve this issue, compile at warning level 3 or higher by supplying /W3, /W4, or /Wall to the compiler, and resolve the warnings emitted." - }, + "shortDescription": null, + "name": "EnableCriticalCompilerWarnings", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } }, { "id": "BA2008", - "name": "EnableControlFlowGuard", "fullDescription": { "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", + "help": { + "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the control flow guard mitigation. As a result, the operating system will force an application to close if an attacker is able to redirect execution in the component to an unexpected location." @@ -948,20 +963,22 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2008EnableControlFlowGuard", - "help": { - "text": "Binaries should enable the compiler control guard feature (CFG) at build time to prevent attackers from redirecting execution to unexpected, unsafe locations. CFG analyzes and discovers all indirect-call instructions at compilation and link time. It also injects a check that precedes every indirect call in code that ensures the target is an expected, safe location. If that check fails at runtime, the operating system will close the program." - }, + "shortDescription": null, + "name": "EnableControlFlowGuard", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } }, { "id": "BA2009", - "name": "EnableAddressSpaceLayoutRandomization", "fullDescription": { "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", + "help": { + "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." + }, "messageStrings": { "Pass": { "text": "'{0}' is properly compiled to enable Address Space Layout Randomization, reducing an attacker's ability to exploit code in well-known locations." @@ -979,20 +996,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2009EnableAddressSpaceLayoutRandomization", - "help": { - "text": "Binaries should linked as DYNAMICBASE to be eligible for relocation by Address Space Layout Randomization (ASLR). ASLR is an important mitigation that makes it more difficult for an attacker to exploit memory corruption vulnerabilities. Configure your tools to build with this feature enabled. For C and C++ binaries, add /DYNAMICBASE to your linker command line. For .NET applications, use a compiler shipping with Visual Studio 2008 or later." - }, + "shortDescription": null, + "name": "EnableAddressSpaceLayoutRandomization", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } }, { "id": "BA2010", - "name": "DoNotMarkImportsSectionAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." + }, "messageStrings": { "Pass": { "text": "'{0}' does not have an imports section that is marked as executable, helping to prevent the exploitation of code vulnerabilities." @@ -1004,20 +1023,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2010DoNotMarkImportsSectionAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. Because the loader will always mark the imports section as writable, it is therefore important to mark this section as non-executable. To resolve this issue, ensure that your program does not mark the imports section executable. Look for uses of /SECTION or /MERGE on the linker command line, or #pragma segment in source code, which change the imports section to be executable, or which merge the \".rdata\" segment into an executable section." - }, + "shortDescription": null, + "name": "DoNotMarkImportsSectionAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } }, { "id": "BA2011", - "name": "EnableStackProtection", "fullDescription": { "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", + "help": { + "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled for all modules, making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities. " @@ -1032,20 +1053,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2011EnableStackProtection", - "help": { - "text": "Binaries should be built with the stack protector buffer security feature (/GS) enabled to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. To resolve this issue, ensure that all modules compiled into the binary are compiled with the stack protector enabled by supplying /GS on the Visual C++ compiler command line." - }, + "shortDescription": null, + "name": "EnableStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } }, { "id": "BA2012", - "name": "DoNotModifyStackProtectionCookie", "fullDescription": { "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", + "help": { + "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly preserves the stack protecter cookie. This has the effect of enabling a significant increase in entropy provided by the operating system over that produced by the C runtime start-up code." @@ -1066,20 +1089,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2012DoNotModifyStackProtectionCookie", - "help": { - "text": "Application code should not interfere with the stack protector. The stack protector (/GS) is a security feature of the compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. The stack protector relies on a random number, called the \"security cookie\", to detect these buffer overflows. This 'cookie' is statically linked with your binary from a Visual C++ library in the form of the symbol __security_cookie. On recent Windows versions, the loader looks for the statically linked value of this cookie, and initializes the cookie with a far better source of entropy -- the system's secure random number generator -- rather than the limited random number generator available early in the C runtime startup code. When this symbol is not the default value, the additional entropy is not injected by the operating system, reducing the effectiveness of the stack protector. To resolve this issue, ensure that your code does not reference or create a symbol named __security_cookie or __security_cookie_complement." - }, + "shortDescription": null, + "name": "DoNotModifyStackProtectionCookie", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } }, { "id": "BA2013", - "name": "InitializeStackProtection", "fullDescription": { "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", + "help": { + "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the buffer security feature that properly initializes the stack protecter. This has the effect of increasing the effectiveness of the feature and reducing spurious detections." @@ -1097,20 +1122,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2013InitializeStackProtection", - "help": { - "text": "Binaries should properly initialize the stack protector (/GS) in order to increase the difficulty of exploiting stack buffer overflow memory corruption vulnerabilities. The stack protector requires access to entropy in order to be effective, which means a binary must initialize a random number generator at startup, by calling __security_init_cookie() as close to the binary's entry point as possible. Failing to do so will result in spurious buffer overflow detections on the part of the stack protector. To resolve this issue, use the default entry point provided by the C runtime, which will make this call for you, or call __security_init_cookie() manually in your custom entry point." - }, + "shortDescription": null, + "name": "InitializeStackProtection", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } }, { "id": "BA2014", - "name": "DoNotDisableStackProtectionForFunctions", "fullDescription": { "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", + "help": { + "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." + }, "messageStrings": { "Pass": { "text": "'{0}' is a C or C++ binary built with the stack protector buffer security feature enabled which does not disable protection for any individual functions (via __declspec(safebuffers), making it more difficult for an attacker to exploit stack buffer overflow memory corruption vulnerabilities." @@ -1122,20 +1149,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2014DoNotDisableStackProtectionForFunctions", - "help": { - "text": "Application code should not disable stack protection for individual functions. The stack protector (/GS) is a security feature of the Windows native compiler which makes it more difficult to exploit stack buffer overflow memory corruption vulnerabilities. Disabling the stack protector, even on a function-by-function basis, can compromise the security of code. To resolve this issue, remove occurrences of __declspec(safebuffers) from your code. If the additional code inserted by the stack protector has been shown in profiling to cause a significant performance problem for your application, attempt to move stack buffer modifications out of the hot path of execution to allow the compiler to avoid inserting stack protector checks in these locations rather than disabling the stack protector altogether." - }, + "shortDescription": null, + "name": "DoNotDisableStackProtectionForFunctions", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } }, { "id": "BA2015", - "name": "EnableHighEntropyVirtualAddresses", "fullDescription": { "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", + "help": { + "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." + }, "messageStrings": { "Pass": { "text": "'{0}' is high entropy ASLR compatible, reducing an attacker's ability to exploit code in well-known locations." @@ -1153,20 +1182,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2015EnableHighEntropyVirtualAddresses", - "help": { - "text": "Binaries should be marked as high entropy Address Space Layout Randomization (ASLR) compatible. High entropy allows ASLR to be more effective in mitigating memory corruption vulnerabilities. To resolve this issue, configure your tool chain to mark the program high entropy compatible; e.g. by supplying /HIGHENTROPYVA to the C or C++ linker command line. Binaries must also be compiled as /LARGEADDRESSAWARE in order to enable high entropy ASLR." - }, + "shortDescription": null, + "name": "EnableHighEntropyVirtualAddresses", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } }, { "id": "BA2016", - "name": "MarkImageAsNXCompatible", "fullDescription": { "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", + "help": { + "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." + }, "messageStrings": { "Pass": { "text": "'{0}' is marked as NX compatible, helping to prevent attackers from executing code that is injected into data segments." @@ -1178,20 +1209,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2016MarkImageAsNXCompatible", - "help": { - "text": "Binaries should be marked as NX compatible to help prevent execution of untrusted data as code. The NXCompat bit, also known as \"Data Execution Prevention\" (DEP) or \"Execute Disable\" (XD), triggers a processor security feature that allows a program to mark a piece of memory as non-executable. This helps mitigate memory corruption vulnerabilities by preventing an attacker from supplying direct shellcode in their exploit (because the exploit comes in the form of input data to the exploited program on a data segment, rather than on an executable code segment). Ensure that your tools are configured to mark your binaries as NX compatible, e.g. by passing /NXCOMPAT to the C/C++ linker." - }, + "shortDescription": null, + "name": "MarkImageAsNXCompatible", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } }, { "id": "BA2018", - "name": "EnableSafeSEH", "fullDescription": { "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", + "help": { + "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." + }, "messageStrings": { "Pass": { "text": "'{0}' is an x86 binary that enables SafeSEH, a mitigation that verifies SEH exception jump targets are defined as exception handlers in the program (and not shellcode)." @@ -1206,20 +1239,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2018EnableSafeSEH", - "help": { - "text": "X86 binaries should enable the SafeSEH mitigation to minimize exploitable memory corruption issues. SafeSEH makes it more difficult to exploit vulnerabilities that permit overwriting SEH control blocks on the stack, by verifying that the location to which a thrown SEH exception would jump is indeed defined as an exception handler in the source program (and not shellcode). To resolve this issue, supply the /SafeSEH flag on the linker command line. Note that you will need to configure your build system to supply this flag for x86 builds only, as the /SafeSEH flag is invalid when linking for ARM and x64." - }, + "shortDescription": null, + "name": "EnableSafeSEH", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } }, { "id": "BA2019", - "name": "DoNotMarkWritableSectionsAsShared", "fullDescription": { "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", + "help": { + "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and writable, helping to prevent the exploitation of code vulnerabilities." @@ -1231,20 +1266,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2019DoNotMarkWritableSectionsAsShared", - "help": { - "text": "Code or data sections should not be marked as both shared and writable. Because these sections are shared across processes, this condition might permit a process with low privilege to alter memory in a higher privilege process. If you do not actually require that a section be both writable and shared, remove one or both of these attributes (by modifying your .DEF file, the appropriate linker /section switch arguments, etc.). If you must share common data across processes (for inter-process communication (IPC) or other purposes) use CreateFileMapping with proper security attributes or an actual IPC mechanism instead (COM, named pipes, LPC, etc.)." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsShared", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } }, { "id": "BA2021", - "name": "DoNotMarkWritableSectionsAsExecutable", "fullDescription": { "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", + "help": { + "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." + }, "messageStrings": { "Pass": { "text": "'{0}' contains no data or code sections marked as both shared and executable, helping to prevent the exploitation of code vulnerabilities." @@ -1259,20 +1296,22 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2021DoNotMarkWritableSectionsAsExecutable", - "help": { - "text": "PE sections should not be marked as both writable and executable. This condition makes it easier for an attacker to exploit memory corruption vulnerabilities, as it may provide an attacker executable location(s) to inject shellcode. To resolve this issue, configure your tools to not emit memory sections that are writable and executable. For example, look for uses of /SECTION on the linker command line for C and C++ programs, or #pragma section in C and C++ source code, which mark a section with both attributes. Be sure to disable incremental linking in release builds, as this feature creates a writable and executable section named '.textbss' in order to function." - }, + "shortDescription": null, + "name": "DoNotMarkWritableSectionsAsExecutable", + "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } }, { "id": "BA2022", - "name": "SignSecurely", "fullDescription": { "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", + "help": { + "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." + }, "messageStrings": { "Pass": { "text": "'{0}' appears to be signed with secure cryptographic algorithms. WinTrustVerify successfully validated the binary but did not attempt to validate certificate chaining or that the root certificate is trusted. The following digitial signature algorithms were detected: {1}" @@ -1290,17 +1329,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2022SignSecurely", - "help": { - "text": "Images should be correctly signed by trusted publishers using cryptographically secure signature algorithms. This rule invokes WinTrustVerify to validate that binary hash, signing and public key algorithms are secure and, where configurable, that key sizes meet acceptable size thresholds." - } + "shortDescription": null, + "name": "SignSecurely", + "guid": null }, { "id": "BA2024", - "name": "EnableSpectreMitigations", "fullDescription": { "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", + "help": { + "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." + }, "messageStrings": { "Warning": { "text": "'{0}' was compiled with one or more modules that do not enable code generation mitigations for speculative execution side-channel attack (Spectre) vulnerabilities. Spectre attacks can compromise hardware-based isolation, allowing non-privileged users to retrieve potentially sensitive data from the CPU cache. To resolve the issue, provide the /Qspectre switch on the compiler command-line (or /d2guardspecload in cases where your compiler supports this switch and it is not possible to update to a toolset that supports /Qspectre). This warning should be addressed for code that operates on data that crosses a trust boundary and that can affect execution, such as parsing untrusted file inputs or processing query strings of a web request.\r\n{1}" @@ -1321,17 +1362,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2024EnableSpectreMitigations", - "help": { - "text": "Application code should be compiled with the Spectre mitigations switch (/Qspectre) and toolsets that support it." - } + "shortDescription": null, + "name": "EnableSpectreMitigations", + "guid": null }, { "id": "BA2025", - "name": "EnableShadowStack", "fullDescription": { "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", + "help": { + "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." + }, "messageStrings": { "Pass": { "text": "'{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation." @@ -1343,17 +1386,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2025EnableShadowStack", - "help": { - "text": "Control-flow Enforcement Technology (CET) Shadow Stack is a computer processor feature that provides capabilities to defend against return-oriented programming (ROP) based malware attacks." - } + "shortDescription": null, + "name": "EnableShadowStack", + "guid": null }, { "id": "BA2026", - "name": "EnableAdditionalSdlSecurityChecks", "fullDescription": { "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", + "help": { + "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." + }, "messageStrings": { "Pass": { "text": "'{0}' is a Windows PE that was compiled with recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features." @@ -1365,17 +1410,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks", - "help": { - "text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." - } + "shortDescription": null, + "name": "EnableAdditionalSdlSecurityChecks", + "guid": null }, { "id": "BA3003", - "name": "EnableStackProtector", "fullDescription": { "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", + "help": { + "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." + }, "messageStrings": { "Pass": { "text": "Stack protector was found on '{0}'. However, if you are not compiling with '--stack-protector-strong', it may provide additional protections." @@ -1387,17 +1434,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3003EnableStackProtector", - "help": { - "text": "The stack protector ensures that all functions that use buffers over a certain size will use a stack cookie (and check it) to prevent stack based buffer overflows, exiting if stack smashing is detected. Use '--fstack-protector-strong' (all buffers of 4 bytes or more) or '--fstack-protector-all' (all functions) to enable this." - } + "shortDescription": null, + "name": "EnableStackProtector", + "guid": null }, { "id": "BA3005", - "name": "EnableStackClashProtection", "fullDescription": { "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", + "help": { + "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." + }, "messageStrings": { "Pass": { "text": "The Stack Clash Protection was present, so '{0}' is protected." @@ -1409,17 +1458,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3005EnableStackClashProtection", - "help": { - "text": "This check ensures that stack clash protection is enabled. Each program running on a computer uses a special memory region called the stack. This memory region is special because it grows automatically when the program needs more stack memory. But if it grows too much and gets too close to another memory region, the program may confuse the stack with the other memory region. An attacker can exploit this confusion to overwrite the stack with the other memory region, or the other way around. Use the compiler flags '-fstack-clash-protection' to enable this." - } + "shortDescription": null, + "name": "EnableStackClashProtection", + "guid": null }, { "id": "BA5001", - "name": "EnablePositionIndependentExecutableMachO", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass": { "text": "PIE enabled on executable '{0}'." @@ -1431,17 +1482,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5001EnablePositionIndependentExecutableMachO", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutableMachO", + "guid": null }, { "id": "BA5002", - "name": "DoNotAllowExecutableStack", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." + }, "messageStrings": { "Pass": { "text": "Executable stack is not allowed on executable '{0}'." @@ -1453,17 +1506,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA5002DoNotAllowExecutableStack", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure do not enable flag \"--allow_stack_execute\"." - } + "shortDescription": null, + "name": "DoNotAllowExecutableStack", + "guid": null }, { "id": "BA3001", - "name": "EnablePositionIndependentExecutable", "fullDescription": { "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", + "help": { + "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." + }, "messageStrings": { "Pass_Executable": { "text": "PIE enabled on executable '{0}'." @@ -1478,17 +1533,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3001EnablePositionIndependentExecutable", - "help": { - "text": "A Position Independent Executable (PIE) relocates all of its sections at load time, including the code section, if ASLR is enabled in the Linux kernel (instead of just the stack/heap). This makes ROP-style attacks more difficult. This can be enabled by passing '-f pie' to clang/gcc." - } + "shortDescription": null, + "name": "EnablePositionIndependentExecutable", + "guid": null }, { "id": "BA3002", - "name": "DoNotMarkStackAsExecutable", "fullDescription": { "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", + "help": { + "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." + }, "messageStrings": { "Pass": { "text": "GNU_STACK segment marked as non-executable on '{0}'." @@ -1503,17 +1560,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3002DoNotMarkStackAsExecutable", - "help": { - "text": "This checks if a binary has an executable stack; an executable stack allows attackers to redirect code flow into stack memory, which is an easy place for an attacker to store shellcode. Ensure you are compiling with '-z noexecstack' to mark the stack as non-executable." - } + "shortDescription": null, + "name": "DoNotMarkStackAsExecutable", + "guid": null }, { "id": "BA3006", - "name": "EnableNonExecutableStack", "fullDescription": { "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", + "help": { + "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." + }, "messageStrings": { "Pass": { "text": "The non-executable stack flag was present, so '{0}' is protected." @@ -1525,17 +1584,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3006EnableNonExecutableStack", - "help": { - "text": "This check ensures that non-executable stack is enabled. A common type of exploit is the stack buffer overflow. An application receives, from an attacker, more data than it is prepared for and stores this information on its stack, writing beyond the space reserved for it. This can be designed to cause execution of the data written on the stack. One mechanism to mitigate this vulnerability is for the system to not allow the execution of instructions in sections of memory identified as part of the stack. Use the compiler flags '-z noexecstack' to enable this." - } + "shortDescription": null, + "name": "EnableNonExecutableStack", + "guid": null }, { "id": "BA3010", - "name": "EnableReadOnlyRelocations", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." + }, "messageStrings": { "Pass": { "text": "The GNU_RELRO segment was present, so '{0}' is protected." @@ -1547,17 +1608,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3010EnableReadOnlyRelocations", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,relro' to enable this." - } + "shortDescription": null, + "name": "EnableReadOnlyRelocations", + "guid": null }, { "id": "BA3011", - "name": "EnableBindNow", "fullDescription": { "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", + "help": { + "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." + }, "messageStrings": { "Pass": { "text": "The BIND_NOW flag was present, so '{0}' is protected." @@ -1569,17 +1632,19 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3011EnableBindNow", - "help": { - "text": "This check ensures that some relocation data is marked as read only after the executable is loaded, and moved below the '.data' section in memory. This prevents them from being overwritten, which can redirect control flow. Use the compiler flags '-Wl,z,now' to enable this." - } + "shortDescription": null, + "name": "EnableBindNow", + "guid": null }, { "id": "BA3030", - "name": "UseCheckedFunctionsWithGcc", "fullDescription": { "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." }, + "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", + "help": { + "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." + }, "messageStrings": { "Pass_AllFunctionsChecked": { "text": "All functions that can be checked in '{0}' are using the checked versions, so this binary is protected from overflows caused by those function's use." @@ -1597,10 +1662,9 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA3030UseCheckedFunctionsWithGcc", - "help": { - "text": "GCC can automatically replace unsafe functions with checked variants when it can statically determine the length of a buffer or string. In the case of an overflow, the checked version will safely exit the program (rather than potentially allowing an exploit). This feature can be enabled by passing '-DFortify_Source=2' when optimization level 2 is enabled ('-O2')." - } + "shortDescription": null, + "name": "UseCheckedFunctionsWithGcc", + "guid": null } ], "properties": { @@ -1625,7 +1689,6 @@ } } ], - "automationDetails": {}, "columnKind": "utf16CodeUnits" } ] From 0ca3e3a19ac287592c4348e15f8751a69c3ce475 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Fri, 7 Jan 2022 01:40:35 -0800 Subject: [PATCH 06/10] update SDK branch to use DataMember.Order and run re-baseline in Binskim --- .../Expected/BinSkim.win-x64.ni.dll.sarif | 98 +++---------------- .../Expected/BinSkim.win-x86.ni.dll.sarif | 98 +++---------------- .../Expected/Binskim.linux-x64.dll.sarif | 94 +++--------------- .../Expected/Binskim.win-x64.RTR.dll.sarif | 98 +++---------------- .../Expected/Binskim.win-x64.dll.sarif | 94 +++--------------- .../Expected/Binskim.win-x86.RTR.dll.sarif | 98 +++---------------- .../Expected/Binskim.win-x86.dll.sarif | 94 +++--------------- ...ore_RTR_linux-x64_VS2019_Default.dll.sarif | 98 +++---------------- ...tCore_RTR_win-x64_VS2019_Default.dll.sarif | 98 +++---------------- ...tCore_RTR_win-x86_VS2019_Default.dll.sarif | 98 +++---------------- ...NetCore_linux-x64_VS2019_Default.dll.sarif | 98 +++---------------- ...otNetCore_win-x64_VS2019_Default.dll.sarif | 98 +++---------------- ...otNetCore_win-x64_VS2019_Default.exe.sarif | 98 +++---------------- ...otNetCore_win-x86_VS2019_Default.dll.sarif | 98 +++---------------- ...InteropAssemblyForAtlTestLibrary.dll.sarif | 94 +++--------------- .../Expected/ManagedResourcesOnly.dll.sarif | 94 +++--------------- ...aged_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif | 98 +++---------------- ...anaged_AnyCPU_VS2017_Prefer32Bit.exe.sarif | 98 +++---------------- .../Managed_x64_VS2015_FSharp.exe.sarif | 98 +++---------------- ...VS2019_CSharp_DebugType_Embedded.dll.sarif | 98 +++---------------- ...x64_VS2019_CSharp_DebugType_Full.dll.sarif | 98 +++---------------- ...x64_VS2019_CSharp_DebugType_None.dll.sarif | 94 +++--------------- ..._VS2019_CSharp_DebugType_PdbOnly.dll.sarif | 98 +++---------------- ...VS2019_CSharp_DebugType_Portable.dll.sarif | 98 +++---------------- ...x64_VS2019_VB_DebugType_Embedded.dll.sarif | 98 +++---------------- ...ged_x64_VS2019_VB_DebugType_Full.dll.sarif | 98 +++---------------- ...ged_x64_VS2019_VB_DebugType_None.dll.sarif | 94 +++--------------- ..._x64_VS2019_VB_DebugType_PdbOnly.dll.sarif | 98 +++---------------- ...x64_VS2019_VB_DebugType_Portable.dll.sarif | 98 +++---------------- .../Expected/Managed_x86_VS2013_Wpf.exe.sarif | 98 +++---------------- .../Managed_x86_VS2015_FSharp.dll.sarif | 98 +++---------------- .../MixedMode_x64_VS2013_Default.dll.sarif | 98 +++---------------- .../MixedMode_x64_VS2013_NoPdb.exe.sarif | 70 +++---------- .../MixedMode_x64_VS2015_Default.exe.sarif | 98 +++---------------- ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 98 +++---------------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 98 +++---------------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 98 +++---------------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 70 +++---------- .../MixedMode_x86_VS2013_Default.exe.sarif | 98 +++---------------- .../MixedMode_x86_VS2013_MissingPdb.dll.sarif | 70 +++---------- .../MixedMode_x86_VS2015_Default.exe.sarif | 98 +++---------------- ...ve_ARM_VS2015_CvtresResourceOnly.dll.sarif | 94 +++--------------- .../Native_x64_VS2013_Default.dll.sarif | 98 +++---------------- ...ve_x64_VS2015_CvtresResourceOnly.dll.sarif | 94 +++--------------- .../Native_x64_VS2015_Default.dll.sarif | 98 +++---------------- ...ve_x64_VS2019_Atl_NoPdbGenerated.dll.sarif | 70 +++---------- ...4_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif | 98 +++---------------- ..._VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif | 98 +++---------------- ..._x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif | 98 +++---------------- ..._x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif | 70 +++---------- .../Native_x64_VS2019_SDL_Enabled.exe.sarif | 98 +++---------------- ...tive_x64_VSCode_Rust_DebugInfo_0.exe.sarif | 98 +++---------------- ...tive_x64_VSCode_Rust_DebugInfo_1.exe.sarif | 98 +++---------------- ...tive_x64_VSCode_Rust_DebugInfo_2.exe.sarif | 98 +++---------------- .../Native_x86_VS2012_SDL_Enabled.exe.sarif | 98 +++---------------- .../Native_x86_VS2013_Default.exe.sarif | 98 +++---------------- .../Native_x86_VS2013_PdbMissing.exe.sarif | 70 +++---------- .../Native_x86_VS2013_ResourceOnly.dll.sarif | 98 +++---------------- ...Native_x86_VS2015_AtlProxyStubPS.dll.sarif | 98 +++---------------- ...ve_x86_VS2015_CvtresResourceOnly.dll.sarif | 94 +++--------------- .../Native_x86_VS2015_Default.exe.sarif | 98 +++---------------- .../Native_x86_VS2015_Default_Debug.dll.sarif | 98 +++---------------- ...ve_x86_VS2017_15.5.4_PdbStripped.dll.sarif | 70 +++---------- .../Native_x86_VS2019_SDL_Enabled.exe.sarif | 98 +++---------------- .../Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif | 98 +++---------------- .../Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif | 76 +++----------- .../Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif | 70 +++---------- .../Expected/Uwp_ARM_VS2017_VB.dll.sarif | 98 +++---------------- ...wp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif | 98 +++---------------- .../Uwp_x64_VS2015_DefaultBlankApp.dll.sarif | 76 +++----------- .../Uwp_x64_VS2015_DefaultBlankApp.exe.sarif | 70 +++---------- .../Expected/Uwp_x64_VS2017_Cpp.dll.sarif | 98 +++---------------- .../Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif | 98 +++---------------- .../Uwp_x86_VS2015_DefaultBlankApp.dll.sarif | 76 +++----------- .../Uwp_x86_VS2015_DefaultBlankApp.exe.sarif | 70 +++---------- .../Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif | 98 +++---------------- .../Wix_3.11.1_VS2017_Bootstrapper.exe.sarif | 98 +++---------------- .../Expected/clang.default_compilation.sarif | 94 +++--------------- .../Expected/clang.elf.objectivec.dwarf.sarif | 98 +++---------------- .../Expected/clang.execstack.sarif | 94 +++--------------- .../Expected/clang.execstack.so.sarif | 94 +++--------------- .../Expected/clang.immediate_binding.sarif | 94 +++--------------- .../Expected/clang.no_immediate_binding.sarif | 94 +++--------------- .../Expected/clang.no_stack_protector.sarif | 94 +++--------------- .../Expected/clang.noexecstack.sarif | 94 +++--------------- .../Expected/clang.noexecstack.so.sarif | 94 +++--------------- .../Expected/clang.non_pie_executable.sarif | 94 +++--------------- .../Expected/clang.object_file.o.sarif | 94 +++--------------- .../Expected/clang.pie_executable.sarif | 94 +++--------------- .../Expected/clang.relocationsro.sarif | 94 +++--------------- .../Expected/clang.relocationsrw.sarif | 94 +++--------------- .../Expected/clang.shared_library.so.sarif | 94 +++--------------- .../Expected/clang.stack_protector.sarif | 94 +++--------------- .../Expected/clang.stack_protector.so.sarif | 94 +++--------------- .../clangcl.pe.cpp.codeview.exe.sarif | 98 +++---------------- .../Expected/gcc.default_compilation.sarif | 94 +++--------------- ...rongsspbuffersize8+fnostackprotector.sarif | 98 +++---------------- .../Expected/gcc.execstack.sarif | 94 +++--------------- .../Expected/gcc.execstack.so.sarif | 94 +++--------------- .../Expected/gcc.fortified.sarif | 94 +++--------------- .../Expected/gcc.gsplitdwarf.5.dwo.sarif | 98 +++---------------- .../Expected/gcc.gsplitdwarf.5.sarif | 98 +++---------------- ...oworld.4.o.no-stack-clash-protection.sarif | 98 +++---------------- ...oworld.5.o.no-stack-clash-protection.sarif | 98 +++---------------- .../gcc.helloworld.execstack.5.o.sarif | 98 +++---------------- .../Expected/gcc.helloworld.nodwarf.sarif | 94 +++--------------- .../gcc.helloworld.noexecstack.5.o.sarif | 98 +++---------------- .../Expected/gcc.immediate_binding.sarif | 94 +++--------------- .../gcc.no_fortification_required.sarif | 94 +++--------------- .../Expected/gcc.no_immediate_binding.sarif | 94 +++--------------- .../Expected/gcc.no_stack_protector.sarif | 94 +++--------------- .../Expected/gcc.noexecstack.sarif | 94 +++--------------- .../Expected/gcc.noexecstack.so.sarif | 94 +++--------------- .../Expected/gcc.non_pie_executable.sarif | 94 +++--------------- ...objcopy.stripall.addgnudebuglink.dbg.sarif | 98 +++---------------- ...gcc.objcopy.stripall.addgnudebuglink.sarif | 94 +++--------------- .../Expected/gcc.object_file.o.sarif | 94 +++--------------- .../gcc.pe.objectivec.dwarf.exe.sarif | 70 +++---------- .../Expected/gcc.pie_executable.sarif | 94 +++--------------- .../Expected/gcc.relocationsro.sarif | 94 +++--------------- .../Expected/gcc.relocationsrw.sarif | 94 +++--------------- .../Expected/gcc.requiredsymbol.4.o.sarif | 98 +++---------------- .../Expected/gcc.requiredsymbol.5.o.sarif | 98 +++---------------- .../Expected/gcc.shared_library.so.sarif | 94 +++--------------- .../Expected/gcc.stack_protector.sarif | 94 +++--------------- .../Expected/gcc.stack_protector.so.sarif | 94 +++--------------- .../Expected/gcc.unfortified.sarif | 94 +++--------------- 127 files changed, 1929 insertions(+), 9955 deletions(-) diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif index 65d6d9d03..6c43d65db 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x64.ni.dll.sarif @@ -808,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -841,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -961,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -994,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1021,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1054,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1081,9 +1063,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1111,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1147,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1171,9 +1147,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1195,9 +1169,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1222,9 +1194,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1249,9 +1219,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1273,9 +1241,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1321,9 +1285,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1345,9 +1307,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1369,9 +1329,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1393,9 +1351,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1423,9 +1379,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1447,9 +1401,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1471,9 +1423,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1495,9 +1445,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1525,9 +1473,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1558,9 +1504,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1621,9 +1563,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1648,9 +1588,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif index ebcc7c5d5..2ff88948d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/BinSkim.win-x86.ni.dll.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1046,9 +1030,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1139,9 +1117,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1163,9 +1139,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1190,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1217,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1241,9 +1211,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1289,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1313,9 +1277,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1337,9 +1299,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1361,9 +1321,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1391,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1439,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1466,9 +1418,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1499,9 +1449,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1526,9 +1474,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif index 6ec50de89..96bd3efce 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.linux-x64.dll.sarif @@ -790,9 +790,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -817,9 +815,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -880,9 +874,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -910,9 +902,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1003,9 +989,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1036,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1063,9 +1045,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1096,9 +1076,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1189,9 +1163,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1237,9 +1207,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1264,9 +1232,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1291,9 +1257,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1315,9 +1279,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1339,9 +1301,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1363,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1387,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1411,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1435,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1465,9 +1417,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1489,9 +1439,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1513,9 +1461,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1540,9 +1486,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1573,9 +1517,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1600,9 +1542,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1630,9 +1570,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif index 64053d782..62462cbb0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.RTR.dll.sarif @@ -808,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -841,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -961,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -994,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1021,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1054,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1081,9 +1063,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1111,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1147,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1171,9 +1147,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1195,9 +1169,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1222,9 +1194,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1249,9 +1219,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1273,9 +1241,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1321,9 +1285,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1345,9 +1307,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1369,9 +1329,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1393,9 +1351,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1423,9 +1379,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1447,9 +1401,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1471,9 +1423,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1495,9 +1445,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1525,9 +1473,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1558,9 +1504,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1621,9 +1563,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1648,9 +1588,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif index 79b1d4cb0..57417ded1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x64.dll.sarif @@ -790,9 +790,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -817,9 +815,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -880,9 +874,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -910,9 +902,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1003,9 +989,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1036,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1063,9 +1045,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1096,9 +1076,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1189,9 +1163,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1237,9 +1207,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1264,9 +1232,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1291,9 +1257,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1315,9 +1279,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1339,9 +1301,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1363,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1387,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1411,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1435,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1465,9 +1417,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1489,9 +1439,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1513,9 +1461,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1540,9 +1486,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1573,9 +1517,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1600,9 +1542,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1630,9 +1570,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif index 50fe6d486..be4a16ba1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.RTR.dll.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1046,9 +1030,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1139,9 +1117,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1163,9 +1139,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1190,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1217,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1241,9 +1211,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1289,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1313,9 +1277,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1337,9 +1299,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1361,9 +1321,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1391,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1439,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1466,9 +1418,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1499,9 +1449,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1526,9 +1474,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif index 933aa32a2..8efdebd1d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Binskim.win-x86.dll.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -876,9 +870,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -906,9 +898,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1032,9 +1016,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1059,9 +1041,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1128,9 +1106,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1176,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1203,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1230,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1254,9 +1222,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1278,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1302,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1350,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1428,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1452,9 +1404,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1479,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1512,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1539,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1569,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1596,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1626,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1659,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif index 9d15fcbc5..55823c135 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_linux-x64_VS2019_Default.dll.sarif @@ -813,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -840,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -903,9 +897,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -933,9 +925,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -960,9 +950,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -990,9 +978,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1026,9 +1012,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1059,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1086,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1119,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1146,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1176,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1212,9 +1186,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1236,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1314,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1338,9 +1302,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1488,9 +1440,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1512,9 +1462,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1716,9 +1652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif index 56b3adc58..f946b8c9a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x64_VS2019_Default.dll.sarif @@ -813,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -840,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -903,9 +897,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -933,9 +925,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -960,9 +950,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -990,9 +978,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1026,9 +1012,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1059,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1086,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1119,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1146,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1176,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1212,9 +1186,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1236,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1314,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1338,9 +1302,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1488,9 +1440,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1512,9 +1462,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1716,9 +1652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif index f1bda8df7..5eeb6b548 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_RTR_win-x86_VS2019_Default.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif index 1c5b99a21..c7076a5bf 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_linux-x64_VS2019_Default.dll.sarif @@ -813,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -840,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -903,9 +897,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -933,9 +925,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -960,9 +950,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -990,9 +978,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1026,9 +1012,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1059,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1086,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1119,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1146,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1176,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1212,9 +1186,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1236,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1314,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1338,9 +1302,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1488,9 +1440,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1512,9 +1462,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1716,9 +1652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif index daeb0d495..cdf60b472 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.dll.sarif @@ -813,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -840,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -903,9 +897,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -933,9 +925,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -960,9 +950,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -990,9 +978,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1026,9 +1012,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1059,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1086,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1119,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1146,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1176,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1212,9 +1186,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1236,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1314,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1338,9 +1302,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1488,9 +1440,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1512,9 +1462,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1716,9 +1652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif index c04c4b3dd..e22dcf742 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x64_VS2019_Default.exe.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -837,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -864,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -897,9 +891,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -927,9 +919,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -960,9 +950,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -987,9 +975,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1014,9 +1000,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1044,9 +1028,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1080,9 +1062,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1104,9 +1084,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1128,9 +1106,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1155,9 +1131,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1206,9 +1178,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1230,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1254,9 +1222,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1278,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1302,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1356,9 +1316,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1380,9 +1338,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1428,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1458,9 +1410,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1488,9 +1438,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1521,9 +1469,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1548,9 +1494,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1644,9 +1584,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1674,9 +1612,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif index 60c860595..d0f304d5f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/DotNetCore_win-x86_VS2019_Default.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif index 29bb9a1ec..300460d03 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedInteropAssemblyForAtlTestLibrary.dll.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -876,9 +870,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -906,9 +898,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1032,9 +1016,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1059,9 +1041,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1128,9 +1106,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1176,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1203,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1230,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1254,9 +1222,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1278,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1302,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1350,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1428,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1452,9 +1404,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1479,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1512,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1539,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1569,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1596,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1626,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1659,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif index 9cb9f5861..376d42a07 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/ManagedResourcesOnly.dll.sarif @@ -789,9 +789,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -816,9 +814,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -879,9 +873,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -909,9 +901,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1002,9 +988,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1035,9 +1019,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1062,9 +1044,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1095,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1188,9 +1162,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1236,9 +1206,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1263,9 +1231,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1290,9 +1256,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1314,9 +1278,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1338,9 +1300,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1362,9 +1322,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1386,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1410,9 +1366,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1434,9 +1388,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1464,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1488,9 +1438,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1512,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1539,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1572,9 +1516,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1599,9 +1541,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1629,9 +1569,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif index b503fe5aa..b44604fdf 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_NoPrefer32Bit.exe.sarif @@ -803,9 +803,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -830,9 +828,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -860,9 +856,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -923,9 +915,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -950,9 +940,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -980,9 +968,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1016,9 +1002,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1049,9 +1033,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1076,9 +1058,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1112,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1136,9 +1114,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1160,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1187,9 +1161,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1214,9 +1186,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1238,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1262,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1286,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1310,9 +1274,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1334,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1358,9 +1318,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1388,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1412,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1436,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1466,9 +1418,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1493,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1526,9 +1474,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1559,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1586,9 +1530,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1616,9 +1558,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1643,9 +1583,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1673,9 +1611,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1706,9 +1642,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif index beb05901c..9e46dd05b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_AnyCPU_VS2017_Prefer32Bit.exe.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -863,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -896,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1052,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1112,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1148,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1172,9 +1148,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1196,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1223,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1250,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1274,9 +1242,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1322,9 +1286,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1346,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1370,9 +1330,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1394,9 +1352,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1424,9 +1380,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1448,9 +1402,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1502,9 +1452,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1529,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif index 89e03df15..3a5b828e6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2015_FSharp.exe.sarif @@ -808,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -835,9 +833,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -898,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -928,9 +920,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -955,9 +945,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -985,9 +973,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1021,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1054,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1081,9 +1063,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1108,9 +1088,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1138,9 +1116,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1174,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1198,9 +1172,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1222,9 +1194,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1249,9 +1219,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1276,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1324,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1348,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1372,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1396,9 +1354,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1420,9 +1376,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1450,9 +1404,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1474,9 +1426,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1498,9 +1448,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1528,9 +1476,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1555,9 +1501,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1588,9 +1532,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1621,9 +1563,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1648,9 +1588,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif index 6c33f0790..8542a50c3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Embedded.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif index cacfafb66..0c6ea83fa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Full.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif index 87178f04a..41f311b97 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_None.dll.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -876,9 +870,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -906,9 +898,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1032,9 +1016,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1059,9 +1041,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1128,9 +1106,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1176,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1203,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1230,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1254,9 +1222,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1278,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1302,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1350,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1428,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1452,9 +1404,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1479,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1512,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1539,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1569,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1596,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1626,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1659,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif index 2545c7a7d..d8dc2e5b8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_PdbOnly.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif index 232ddc41f..baace4b16 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_CSharp_DebugType_Portable.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif index de3e04dfc..0520c9879 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Embedded.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif index 366d4741c..d2d9e2629 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Full.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif index 3b1516b1b..ae52f39d6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_None.dll.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -876,9 +870,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -906,9 +898,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1032,9 +1016,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1059,9 +1041,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1128,9 +1106,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1176,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1203,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1230,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1254,9 +1222,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1278,9 +1244,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1302,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1350,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1428,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1452,9 +1404,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1479,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1512,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1539,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1569,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1596,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1626,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1659,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif index cf3650996..6e6aafd03 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_PdbOnly.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif index 4aadd4f96..f803bb07c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x64_VS2019_VB_DebugType_Portable.dll.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -929,9 +921,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1055,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1082,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1151,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1199,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1226,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1253,9 +1223,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1277,9 +1245,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1301,9 +1267,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1325,9 +1289,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1349,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1373,9 +1333,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1397,9 +1355,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1427,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1475,9 +1427,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1622,9 +1564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1649,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1679,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif index e5c573d30..8118c6ca6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2013_Wpf.exe.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -863,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -896,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1052,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1112,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1148,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1172,9 +1148,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1196,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1223,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1250,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1274,9 +1242,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1322,9 +1286,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1346,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1370,9 +1330,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1394,9 +1352,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1424,9 +1380,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1448,9 +1402,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1502,9 +1452,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1529,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif index 419e0dcdc..98061a657 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Managed_x86_VS2015_FSharp.dll.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -863,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -896,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1052,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1112,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1148,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1172,9 +1148,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1196,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1223,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1250,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1274,9 +1242,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1322,9 +1286,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1346,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1370,9 +1330,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1394,9 +1352,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1424,9 +1380,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1448,9 +1402,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1502,9 +1452,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1529,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif index 5c7311b7b..95a41397e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_Default.dll.sarif @@ -810,9 +810,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -843,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -900,9 +894,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -930,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -957,9 +947,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -981,9 +969,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1005,9 +991,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1029,9 +1013,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1077,9 +1057,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1101,9 +1079,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1131,9 +1107,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1155,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1179,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1203,9 +1173,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1230,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1263,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1290,9 +1254,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1320,9 +1282,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1353,9 +1313,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1386,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1413,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1443,9 +1397,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1479,9 +1431,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1512,9 +1462,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1596,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1662,9 +1602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1686,9 +1624,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1710,9 +1646,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif index 8f997e867..84d8f59c3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2013_NoPdb.exe.sarif @@ -569,9 +569,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -596,9 +594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -626,9 +622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -656,9 +650,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -683,9 +675,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -707,9 +697,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -731,9 +719,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -755,9 +741,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -779,9 +763,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -803,9 +785,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -827,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -857,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -881,9 +857,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -905,9 +879,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -929,9 +901,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -959,9 +929,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -992,9 +960,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1019,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1055,9 +1019,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1088,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1115,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1145,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1178,9 +1134,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif index d8fb13d6d..c7a7030bc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2015_Default.exe.sarif @@ -808,9 +808,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -835,9 +833,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -895,9 +889,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -922,9 +914,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -946,9 +936,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -970,9 +958,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -994,9 +980,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1018,9 +1002,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1042,9 +1024,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1066,9 +1046,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1096,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1120,9 +1096,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1144,9 +1118,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1168,9 +1140,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1195,9 +1165,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1228,9 +1196,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1255,9 +1221,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1285,9 +1249,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1318,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1351,9 +1311,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1378,9 +1336,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1408,9 +1364,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1477,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1504,9 +1454,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1537,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1564,9 +1510,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1627,9 +1569,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1660,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1684,9 +1622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index c3858194b..13441c362 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -844,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -871,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -958,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -982,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1006,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1030,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1078,9 +1058,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1102,9 +1080,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1132,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1156,9 +1130,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1180,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1204,9 +1174,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1231,9 +1199,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1264,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1291,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1354,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1387,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1414,9 +1370,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1480,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1513,9 +1463,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1597,9 +1541,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1663,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1687,9 +1625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index 281195b9d..dabf629dd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -844,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -871,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -958,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -982,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1006,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1030,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1078,9 +1058,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1102,9 +1080,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1132,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1156,9 +1130,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1180,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1204,9 +1174,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1231,9 +1199,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1264,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1291,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1354,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1387,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1414,9 +1370,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1480,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1513,9 +1463,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1597,9 +1541,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1663,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1687,9 +1625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index e8753fd8d..714196152 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -844,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -871,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -958,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -982,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1006,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1030,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1078,9 +1058,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1102,9 +1080,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1132,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1156,9 +1130,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1180,9 +1152,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1204,9 +1174,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1231,9 +1199,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1264,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1291,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1354,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1387,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1414,9 +1370,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1480,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1513,9 +1463,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1597,9 +1541,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1663,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1687,9 +1625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index 9fd342723..8e43b9e59 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -571,9 +571,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -604,9 +602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -631,9 +627,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -661,9 +655,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -691,9 +683,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -718,9 +708,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -742,9 +730,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -766,9 +752,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -790,9 +774,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -814,9 +796,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -838,9 +818,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -862,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -892,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -916,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -940,9 +912,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -964,9 +934,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -994,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1027,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1054,9 +1018,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1090,9 +1052,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1117,9 +1077,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1147,9 +1105,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1180,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif index a9164171b..15b954d5f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_Default.exe.sarif @@ -802,9 +802,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -832,9 +830,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -862,9 +858,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -889,9 +883,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -913,9 +905,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -961,9 +949,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -985,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1009,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1033,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1063,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1087,9 +1065,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1111,9 +1087,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1135,9 +1109,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1168,9 +1140,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1195,9 +1165,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1225,9 +1193,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1258,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1291,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1318,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1348,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1384,9 +1342,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1417,9 +1373,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1477,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1504,9 +1454,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1591,9 +1535,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1624,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1657,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1681,9 +1619,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1705,9 +1641,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif index 40d87b128..fab135633 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2013_MissingPdb.dll.sarif @@ -566,9 +566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -596,9 +594,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -629,9 +625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -659,9 +653,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -686,9 +678,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -710,9 +700,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -734,9 +722,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -758,9 +744,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -782,9 +766,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -806,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -830,9 +810,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -860,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -884,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -908,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -935,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -968,9 +938,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -995,9 +963,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1031,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1058,9 +1022,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1088,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1115,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1145,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1178,9 +1134,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif index b2567f3bc..cf6a8bc4d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/MixedMode_x86_VS2015_Default.exe.sarif @@ -802,9 +802,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -832,9 +830,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -862,9 +858,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -889,9 +883,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -913,9 +905,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -961,9 +949,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -985,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1009,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1033,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1063,9 +1043,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1087,9 +1065,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1111,9 +1087,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1135,9 +1109,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1168,9 +1140,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1195,9 +1165,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1225,9 +1193,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1258,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1291,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1318,9 +1280,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1348,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1384,9 +1342,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1417,9 +1373,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1444,9 +1398,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1477,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1504,9 +1454,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1591,9 +1535,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1624,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1657,9 +1597,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1681,9 +1619,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1705,9 +1641,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif index fc34cd4d0..19fdf00ea 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_ARM_VS2015_CvtresResourceOnly.dll.sarif @@ -788,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -815,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -845,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -878,9 +872,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -908,9 +900,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -938,9 +928,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -974,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1034,9 +1018,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1067,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1094,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1124,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1160,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1184,9 +1158,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1235,9 +1205,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1262,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1286,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1310,9 +1274,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1334,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1358,9 +1318,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1382,9 +1340,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1406,9 +1362,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1436,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1460,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1484,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1511,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1544,9 +1490,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1571,9 +1515,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1598,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1628,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif index 17bcc6e90..66059aa34 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2013_Default.dll.sarif @@ -812,9 +812,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -845,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -872,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -902,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -932,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -959,9 +949,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1031,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1055,9 +1037,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1079,9 +1059,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1103,9 +1081,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1133,9 +1109,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1157,9 +1131,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1181,9 +1153,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1205,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1232,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1265,9 +1231,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1292,9 +1256,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1322,9 +1284,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1355,9 +1315,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1388,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1445,9 +1399,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1481,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1514,9 +1464,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1541,9 +1489,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1568,9 +1514,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1598,9 +1542,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1631,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1664,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1688,9 +1626,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif index 03ce70d6a..9032c9d7f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_CvtresResourceOnly.dll.sarif @@ -788,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -815,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -845,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -878,9 +872,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -908,9 +900,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -938,9 +928,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -974,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1034,9 +1018,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1067,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1094,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1124,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1160,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1184,9 +1158,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1235,9 +1205,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1262,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1286,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1310,9 +1274,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1334,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1358,9 +1318,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1382,9 +1340,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1406,9 +1362,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1436,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1460,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1484,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1511,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1544,9 +1490,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1571,9 +1515,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1598,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1628,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif index 1477baf9f..d871a6de1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2015_Default.dll.sarif @@ -812,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -839,9 +837,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -869,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -899,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -950,9 +940,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -974,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -998,9 +984,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1022,9 +1006,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1046,9 +1028,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1070,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1100,9 +1078,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1124,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1148,9 +1122,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1172,9 +1144,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1199,9 +1169,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1232,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1259,9 +1225,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1289,9 +1253,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1322,9 +1284,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1352,9 +1312,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1385,9 +1343,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1412,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1442,9 +1396,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1478,9 +1430,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1511,9 +1461,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1538,9 +1486,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1595,9 +1539,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1628,9 +1570,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1661,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1685,9 +1623,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif index 0af238da9..a806bccd9 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_Atl_NoPdbGenerated.dll.sarif @@ -571,9 +571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -598,9 +596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -628,9 +624,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -658,9 +652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -685,9 +677,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -709,9 +699,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -733,9 +721,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -757,9 +743,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -781,9 +765,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -805,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -829,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -859,9 +837,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -883,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -907,9 +881,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -931,9 +903,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -961,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -991,9 +959,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1024,9 +990,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1051,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1087,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1114,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1144,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1177,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif index 6c3f13f61..054c162aa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_DEFAULT.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -838,9 +836,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -898,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -925,9 +917,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -949,9 +939,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -973,9 +961,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1021,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1045,9 +1027,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1069,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1099,9 +1077,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1123,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1147,9 +1121,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1171,9 +1143,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1198,9 +1168,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1231,9 +1199,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1258,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1288,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1351,9 +1311,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1384,9 +1342,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1411,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1441,9 +1395,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1477,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1510,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1537,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1564,9 +1510,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1627,9 +1569,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1660,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1684,9 +1622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif index a61379755..d1c5f94b6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FASTLINK.dll.sarif @@ -792,9 +792,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -819,9 +817,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -849,9 +845,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -879,9 +873,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -906,9 +898,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -930,9 +920,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -954,9 +942,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -978,9 +964,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1002,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1026,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1050,9 +1030,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1080,9 +1058,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1104,9 +1080,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1128,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1152,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1179,9 +1149,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1212,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1239,9 +1205,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1269,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1302,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1332,9 +1292,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1365,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1392,9 +1348,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1422,9 +1376,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1458,9 +1410,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1491,9 +1441,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1518,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1545,9 +1491,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1575,9 +1519,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1689,9 +1625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif index a5eb4726f..6e7945105 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_FULL.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -838,9 +836,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -898,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -925,9 +917,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -949,9 +939,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -973,9 +961,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1021,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1045,9 +1027,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1069,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1099,9 +1077,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1123,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1147,9 +1121,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1171,9 +1143,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1198,9 +1168,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1231,9 +1199,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1258,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1288,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1351,9 +1311,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1384,9 +1342,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1411,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1441,9 +1395,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1477,9 +1429,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1510,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1537,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1564,9 +1510,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1627,9 +1569,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1660,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1684,9 +1622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif index e365fd876..8a4f25a9b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_CPlusPlus_DEBUG_NONE.dll.sarif @@ -571,9 +571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -598,9 +596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -628,9 +624,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -658,9 +652,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -685,9 +677,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -709,9 +699,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -733,9 +721,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -757,9 +743,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -781,9 +765,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -805,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -829,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -859,9 +837,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -883,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -907,9 +881,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -931,9 +903,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -961,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -991,9 +959,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1024,9 +990,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1051,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1087,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1114,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1144,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1177,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif index 062e9c375..30520d43a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VS2019_SDL_Enabled.exe.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -834,9 +832,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -864,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -891,9 +885,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -915,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -939,9 +929,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -963,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -987,9 +973,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1011,9 +995,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1035,9 +1017,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1065,9 +1045,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1089,9 +1067,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1113,9 +1089,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1137,9 +1111,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1164,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1197,9 +1167,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1224,9 +1192,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1254,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1287,9 +1251,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1317,9 +1279,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1350,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1377,9 +1335,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1407,9 +1363,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1443,9 +1397,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1476,9 +1428,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1503,9 +1453,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1563,9 +1509,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1659,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif index c0d25e497..9935e605a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_0.exe.sarif @@ -779,9 +779,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -809,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -839,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -866,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -890,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -914,9 +904,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -938,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -962,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -986,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1010,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1040,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1064,9 +1042,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1088,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1112,9 +1086,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1139,9 +1111,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1172,9 +1142,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1199,9 +1167,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1229,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1262,9 +1226,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1292,9 +1254,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1325,9 +1285,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1352,9 +1310,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1382,9 +1338,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1418,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1451,9 +1403,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1478,9 +1428,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1511,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1538,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1568,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1601,9 +1543,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1634,9 +1574,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1658,9 +1596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1682,9 +1618,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif index f80f85b9c..95879d033 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_1.exe.sarif @@ -801,9 +801,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -861,9 +857,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -888,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -912,9 +904,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -960,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -984,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1008,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1032,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1062,9 +1042,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1086,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1110,9 +1086,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1134,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1161,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1194,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1221,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1251,9 +1217,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1284,9 +1248,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1314,9 +1276,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1347,9 +1307,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1440,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1473,9 +1425,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1500,9 +1450,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1590,9 +1534,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1623,9 +1565,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1656,9 +1596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1680,9 +1618,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1704,9 +1640,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif index 27a0be62c..ccb761236 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x64_VSCode_Rust_DebugInfo_2.exe.sarif @@ -801,9 +801,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -861,9 +857,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -888,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -912,9 +904,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -960,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -984,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1008,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1032,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1062,9 +1042,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1086,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1110,9 +1086,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1134,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1161,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1194,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1221,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1251,9 +1217,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1284,9 +1248,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1314,9 +1276,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1347,9 +1307,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1440,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1473,9 +1425,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1500,9 +1450,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1590,9 +1534,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1623,9 +1565,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1656,9 +1596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1680,9 +1618,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1704,9 +1640,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif index d062bfb89..66eed0aa6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2012_SDL_Enabled.exe.sarif @@ -807,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -837,9 +835,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -900,9 +894,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -927,9 +919,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -951,9 +941,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -975,9 +963,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1047,9 +1029,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1071,9 +1051,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1101,9 +1079,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1125,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1149,9 +1123,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1173,9 +1145,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1206,9 +1176,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1233,9 +1201,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1263,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1296,9 +1260,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1329,9 +1291,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1356,9 +1316,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1386,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1422,9 +1378,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1455,9 +1409,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1509,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1596,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1662,9 +1602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1686,9 +1624,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1710,9 +1646,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif index bfb9813c5..42bb4375c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_Default.exe.sarif @@ -807,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -837,9 +835,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -870,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -900,9 +894,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -927,9 +919,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -951,9 +941,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -975,9 +963,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1047,9 +1029,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1071,9 +1051,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1101,9 +1079,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1125,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1149,9 +1123,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1173,9 +1145,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1206,9 +1176,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1233,9 +1201,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1263,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1296,9 +1260,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1329,9 +1291,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1356,9 +1316,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1386,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1422,9 +1378,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1455,9 +1409,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1509,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1596,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1662,9 +1602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1686,9 +1624,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1710,9 +1646,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif index 24cc42147..929259100 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_PdbMissing.exe.sarif @@ -566,9 +566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -596,9 +594,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -629,9 +625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -659,9 +653,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -686,9 +678,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -710,9 +700,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -734,9 +722,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -758,9 +744,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -782,9 +766,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -806,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -830,9 +810,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -860,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -884,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -908,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -935,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -968,9 +938,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -995,9 +963,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1031,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1058,9 +1022,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1088,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1115,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1145,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1178,9 +1134,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif index 422cc36ba..b29612c1f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2013_ResourceOnly.dll.sarif @@ -811,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -838,9 +836,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -901,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -931,9 +923,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -961,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -997,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1030,9 +1016,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1057,9 +1041,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1090,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1117,9 +1097,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1147,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1183,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1207,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1231,9 +1203,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1258,9 +1228,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1285,9 +1253,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1309,9 +1275,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1357,9 +1319,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1381,9 +1341,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1405,9 +1363,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1429,9 +1385,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1537,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1564,9 +1510,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1597,9 +1541,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1624,9 +1566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1651,9 +1591,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1681,9 +1619,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1714,9 +1650,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif index d964961a0..29983f715 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_AtlProxyStubPS.dll.sarif @@ -803,9 +803,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -917,9 +909,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -941,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -965,9 +953,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -989,9 +975,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1013,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1037,9 +1019,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1067,9 +1047,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1091,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1115,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1139,9 +1113,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1172,9 +1144,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1199,9 +1169,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1229,9 +1197,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1262,9 +1228,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1292,9 +1256,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1325,9 +1287,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1352,9 +1312,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1382,9 +1340,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1418,9 +1374,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1478,9 +1430,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1535,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1625,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1658,9 +1598,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1706,9 +1642,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif index b4bfdd928..13aff9024 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_CvtresResourceOnly.dll.sarif @@ -788,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -815,9 +813,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -845,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -878,9 +872,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -908,9 +900,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -938,9 +928,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -974,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1034,9 +1018,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1067,9 +1049,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1094,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1124,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1160,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1184,9 +1158,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1235,9 +1205,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1262,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1286,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1310,9 +1274,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1334,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1358,9 +1318,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1382,9 +1340,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1406,9 +1362,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1436,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1460,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1484,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1511,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1544,9 +1490,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1571,9 +1515,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1598,9 +1540,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1628,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif index 74c363ff2..f4d840892 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default.exe.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -837,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -867,9 +863,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -894,9 +888,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -918,9 +910,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -942,9 +932,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -966,9 +954,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -990,9 +976,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1014,9 +998,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1038,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1068,9 +1048,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1092,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1116,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1140,9 +1114,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1173,9 +1145,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1200,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1230,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1263,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1293,9 +1257,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1353,9 +1313,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1383,9 +1341,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1419,9 +1375,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1452,9 +1406,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1479,9 +1431,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1563,9 +1509,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1659,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif index ced2de24f..ad6747277 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2015_Default_Debug.dll.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -837,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -867,9 +863,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -894,9 +888,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -918,9 +910,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -942,9 +932,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -966,9 +954,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -990,9 +976,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1014,9 +998,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1038,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1068,9 +1048,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1092,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1116,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1140,9 +1114,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1173,9 +1145,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1200,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1230,9 +1198,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1263,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1293,9 +1257,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1326,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1353,9 +1313,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1383,9 +1341,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1419,9 +1375,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1452,9 +1406,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1479,9 +1431,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1563,9 +1509,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1626,9 +1568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1659,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1683,9 +1621,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif index 7f165a3e4..7f9ace01e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2017_15.5.4_PdbStripped.dll.sarif @@ -564,9 +564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -597,9 +595,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -627,9 +623,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -654,9 +648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -678,9 +670,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -702,9 +692,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -726,9 +714,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -750,9 +736,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -774,9 +758,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -798,9 +780,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -828,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -852,9 +830,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -876,9 +852,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -903,9 +877,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -933,9 +905,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -966,9 +936,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -993,9 +961,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1029,9 +995,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1056,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1086,9 +1048,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1113,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1143,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1176,9 +1132,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif index f4ecb2572..815688fa4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Native_x86_VS2019_SDL_Enabled.exe.sarif @@ -803,9 +803,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -917,9 +909,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -941,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -965,9 +953,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -989,9 +975,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1013,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1037,9 +1019,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1067,9 +1047,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1091,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1115,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1139,9 +1113,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1172,9 +1144,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1199,9 +1169,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1229,9 +1197,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1262,9 +1228,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1292,9 +1256,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1325,9 +1287,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1352,9 +1312,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1382,9 +1340,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1418,9 +1374,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1451,9 +1405,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1478,9 +1430,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1535,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1625,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1658,9 +1598,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1706,9 +1642,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif index 68ef9a93e..4feb22244 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM64_VS2019_Cpp.dll.sarif @@ -820,9 +820,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -847,9 +845,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -877,9 +873,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -913,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -937,9 +929,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -961,9 +951,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -988,9 +976,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1015,9 +1001,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1039,9 +1023,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1063,9 +1045,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1087,9 +1067,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1111,9 +1089,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1135,9 +1111,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1159,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1189,9 +1161,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1213,9 +1183,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1237,9 +1205,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1261,9 +1227,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1288,9 +1252,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1321,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1348,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1378,9 +1336,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1411,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1441,9 +1395,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1474,9 +1426,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1501,9 +1451,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1531,9 +1479,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1600,9 +1544,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1627,9 +1569,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1654,9 +1594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1684,9 +1622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1717,9 +1653,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif index d86c3a995..a5b456f82 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.dll.sarif @@ -642,9 +642,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -672,9 +670,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -702,9 +698,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -738,9 +732,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -771,9 +763,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -798,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -831,9 +819,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -861,9 +847,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -891,9 +875,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -918,9 +900,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -942,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -966,9 +944,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -990,9 +966,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1014,9 +988,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1038,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1062,9 +1032,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1092,9 +1060,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1116,9 +1082,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1140,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1167,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1200,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1227,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1254,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1281,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1311,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1344,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif index 2bdc140b4..d356d8b5b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2015_DefaultBlankApp.exe.sarif @@ -568,9 +568,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -598,9 +596,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -631,9 +627,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -661,9 +655,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -691,9 +683,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -718,9 +708,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -742,9 +730,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -766,9 +752,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -790,9 +774,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -814,9 +796,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -838,9 +818,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -862,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -892,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -916,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -940,9 +912,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -967,9 +937,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1000,9 +968,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1063,9 +1027,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1090,9 +1052,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1117,9 +1077,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1147,9 +1105,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1180,9 +1136,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif index a9363ccc4..317a07eaa 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_ARM_VS2017_VB.dll.sarif @@ -808,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -835,9 +833,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -898,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -928,9 +920,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -955,9 +945,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -985,9 +973,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1021,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1054,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1081,9 +1063,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1114,9 +1094,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1144,9 +1122,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1180,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1204,9 +1178,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1228,9 +1200,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1255,9 +1225,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1282,9 +1250,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1306,9 +1272,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1354,9 +1316,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1378,9 +1338,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1402,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1426,9 +1382,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1456,9 +1410,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1480,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1504,9 +1454,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1621,9 +1563,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1648,9 +1588,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif index f460a1e68..b2a40a893 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_AnyCpu_VS2019_Vb_ClassLibrary.dll.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -863,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -896,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1052,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1112,9 +1092,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1148,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1172,9 +1148,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1196,9 +1170,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1223,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1250,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1274,9 +1242,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1322,9 +1286,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1346,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1370,9 +1330,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1394,9 +1352,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1424,9 +1380,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1448,9 +1402,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2004", @@ -1502,9 +1452,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1529,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif index 2a95faac1..dc600b2a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.dll.sarif @@ -645,9 +645,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -675,9 +673,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -711,9 +707,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -744,9 +738,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -771,9 +763,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -804,9 +794,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -831,9 +819,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -861,9 +847,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -891,9 +875,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -918,9 +900,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -942,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -966,9 +944,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -990,9 +966,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1014,9 +988,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1038,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1062,9 +1032,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1092,9 +1060,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1116,9 +1082,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1140,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1164,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1194,9 +1154,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1227,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1254,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1281,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1311,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1344,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif index f50bbe73a..a204b13bc 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2015_DefaultBlankApp.exe.sarif @@ -569,9 +569,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -596,9 +594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -626,9 +622,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -656,9 +650,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -683,9 +675,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -707,9 +697,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -731,9 +719,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -755,9 +741,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -779,9 +763,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -803,9 +785,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -827,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -857,9 +835,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -881,9 +857,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -905,9 +879,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -929,9 +901,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -959,9 +929,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -992,9 +960,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1019,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1055,9 +1019,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1088,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1115,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1145,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1178,9 +1134,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif index f4d8de87c..0278ded2f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2017_Cpp.dll.sarif @@ -812,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -845,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -881,9 +877,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -905,9 +899,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -929,9 +921,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1031,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1055,9 +1037,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1079,9 +1059,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1103,9 +1081,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1127,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1157,9 +1131,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1181,9 +1153,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1205,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1229,9 +1197,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1262,9 +1228,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1289,9 +1253,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1319,9 +1281,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1352,9 +1312,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1382,9 +1340,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1442,9 +1396,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1508,9 +1458,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1541,9 +1489,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1568,9 +1514,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1595,9 +1539,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1625,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1652,9 +1592,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1715,9 +1651,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif index 2ab54d3e3..50a1ecc3e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x64_VS2019_Cpp_DirectX12.exe.sarif @@ -812,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -842,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -878,9 +874,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -902,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -980,9 +968,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1004,9 +990,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1028,9 +1012,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1052,9 +1034,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1076,9 +1056,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1100,9 +1078,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1124,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1154,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1178,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1202,9 +1172,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1226,9 +1194,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1253,9 +1219,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1286,9 +1250,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1313,9 +1275,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1343,9 +1303,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1376,9 +1334,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1406,9 +1362,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1439,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1466,9 +1418,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1496,9 +1446,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1625,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1652,9 +1592,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1715,9 +1651,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif index ac694af16..b8fbf1d45 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.dll.sarif @@ -640,9 +640,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -670,9 +668,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -700,9 +696,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -736,9 +730,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -769,9 +761,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -796,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -829,9 +817,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -859,9 +845,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -886,9 +870,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -910,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -934,9 +914,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -958,9 +936,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -982,9 +958,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1006,9 +980,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1030,9 +1002,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1060,9 +1030,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1084,9 +1052,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1108,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1135,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1168,9 +1130,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1195,9 +1155,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1222,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1252,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1279,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1309,9 +1261,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1342,9 +1292,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif index 10468401e..48497a80d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2015_DefaultBlankApp.exe.sarif @@ -566,9 +566,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -596,9 +594,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -629,9 +625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -659,9 +653,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -686,9 +678,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -710,9 +700,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -734,9 +722,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -758,9 +744,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -782,9 +766,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -806,9 +788,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -830,9 +810,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -860,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -884,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -908,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -935,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -968,9 +938,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -995,9 +963,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1031,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1058,9 +1022,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1088,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1115,9 +1075,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1145,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1178,9 +1134,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif index 8201480c5..fa8670fd6 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Uwp_x86_VS2017_Cpp_DirectX11.exe.sarif @@ -812,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -845,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -881,9 +877,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -905,9 +899,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -929,9 +921,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -956,9 +946,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -983,9 +971,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1007,9 +993,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1031,9 +1015,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1055,9 +1037,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1079,9 +1059,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1103,9 +1081,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1127,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1157,9 +1131,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1181,9 +1153,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1205,9 +1175,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2002", @@ -1229,9 +1197,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1262,9 +1228,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1289,9 +1253,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1319,9 +1281,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1352,9 +1312,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1382,9 +1340,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1442,9 +1396,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1472,9 +1424,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1508,9 +1458,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1541,9 +1489,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1568,9 +1514,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1595,9 +1539,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1625,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1652,9 +1592,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1715,9 +1651,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif index 03b323971..38aaad5c5 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/Wix_3.11.1_VS2017_Bootstrapper.exe.sarif @@ -806,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -833,9 +831,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -866,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2006", @@ -893,9 +887,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -956,9 +946,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -986,9 +974,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1019,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1046,9 +1030,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1139,9 +1117,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1163,9 +1139,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1190,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1217,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1241,9 +1211,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1289,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1313,9 +1277,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1337,9 +1299,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1361,9 +1321,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1391,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1415,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1439,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -1466,9 +1418,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1499,9 +1449,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1526,9 +1474,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1562,9 +1508,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1589,9 +1533,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1619,9 +1561,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1646,9 +1586,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1709,9 +1645,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif index 572a4f33e..bbdc49129 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.default_compilation.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif index cdbd59af4..7b2f7e84b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.elf.objectivec.dwarf.sarif @@ -808,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -835,9 +833,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -868,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -895,9 +889,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -925,9 +917,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -958,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -988,9 +976,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1021,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1048,9 +1032,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1078,9 +1060,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1114,9 +1094,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1147,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1174,9 +1150,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1207,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1234,9 +1206,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1264,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1291,9 +1259,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1321,9 +1287,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1354,9 +1318,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1387,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1411,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1435,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1459,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1483,9 +1437,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1513,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1537,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1561,9 +1509,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1588,9 +1534,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1615,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3004", @@ -1639,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3006", @@ -1663,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1687,9 +1625,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1711,9 +1647,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif index c6c2dd4c7..0e544ef02 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1489,9 +1441,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1513,9 +1463,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1537,9 +1485,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1564,9 +1510,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1591,9 +1535,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1615,9 +1557,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1639,9 +1579,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif index ced8d21a8..006f5ebd4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.execstack.so.sarif @@ -785,9 +785,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -812,9 +810,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -845,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -872,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -902,9 +894,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -935,9 +925,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -965,9 +953,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -998,9 +984,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1025,9 +1009,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1055,9 +1037,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1091,9 +1071,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1124,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1151,9 +1127,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1184,9 +1158,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1211,9 +1183,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1241,9 +1211,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1268,9 +1236,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1331,9 +1295,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1364,9 +1326,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1388,9 +1348,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1412,9 +1370,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1436,9 +1392,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1460,9 +1414,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1490,9 +1442,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1514,9 +1464,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1538,9 +1486,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1616,9 +1558,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1640,9 +1580,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1664,9 +1602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif index 71ea0b041..2f71a5cf8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.immediate_binding.sarif @@ -787,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -814,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -874,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -904,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1000,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +1011,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1057,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1093,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1126,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1186,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1243,9 +1213,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1270,9 +1238,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1366,9 +1328,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1390,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1414,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1438,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1462,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1492,9 +1444,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1516,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1618,9 +1560,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1642,9 +1582,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1666,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif index 37f9d23aa..43b92a5a0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_immediate_binding.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif index 55fb931a0..ed0c44d0c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.no_stack_protector.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif index 5c58272b9..e43b55a5d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif index e2c05f952..46fb26cc1 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.noexecstack.so.sarif @@ -787,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -814,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -874,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -904,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1000,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +1011,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1057,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1093,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1126,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1186,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1243,9 +1213,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1270,9 +1238,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1366,9 +1328,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1390,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1414,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1438,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1462,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1492,9 +1444,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1516,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1618,9 +1560,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1642,9 +1582,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1666,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif index 6a78d0a88..02ef550bd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.non_pie_executable.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif index d5ff61efa..0a41131de 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.object_file.o.sarif @@ -798,9 +798,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -825,9 +823,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -858,9 +854,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -885,9 +879,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -915,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -948,9 +938,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -978,9 +966,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1011,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1038,9 +1022,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1068,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1104,9 +1084,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1137,9 +1115,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1164,9 +1140,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1197,9 +1171,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1224,9 +1196,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1254,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1281,9 +1249,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1311,9 +1277,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1344,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1377,9 +1339,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1401,9 +1361,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1425,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1452,9 +1408,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1479,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1503,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1527,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1551,9 +1499,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1575,9 +1521,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1599,9 +1543,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1677,9 +1615,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif index cd0f0024b..0b2801743 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.pie_executable.sarif @@ -787,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -814,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -874,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -904,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1000,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +1011,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1057,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1093,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1126,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1186,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1243,9 +1213,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1270,9 +1238,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1366,9 +1328,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1390,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1414,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1438,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1462,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1492,9 +1444,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1516,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1618,9 +1560,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1642,9 +1582,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1666,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif index 615a3ae24..68c182933 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsro.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif index eb99839b5..7147c90cf 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.relocationsrw.sarif @@ -785,9 +785,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -812,9 +810,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -845,9 +841,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -872,9 +866,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -902,9 +894,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -935,9 +925,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -965,9 +953,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -998,9 +984,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1025,9 +1009,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1055,9 +1037,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1091,9 +1071,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1124,9 +1102,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1151,9 +1127,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1184,9 +1158,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1211,9 +1183,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1241,9 +1211,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1268,9 +1236,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1298,9 +1264,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1331,9 +1295,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1364,9 +1326,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1388,9 +1348,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1412,9 +1370,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1436,9 +1392,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1460,9 +1414,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1490,9 +1442,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1514,9 +1464,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1538,9 +1486,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1565,9 +1511,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1592,9 +1536,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1616,9 +1558,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1640,9 +1580,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1664,9 +1602,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif index c80e665bb..c48dcf63a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.shared_library.so.sarif @@ -787,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -814,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -874,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -904,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1000,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +1011,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1057,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1093,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1126,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1186,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1243,9 +1213,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1270,9 +1238,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1366,9 +1328,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1390,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1414,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1438,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1462,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1492,9 +1444,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1516,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1618,9 +1560,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1642,9 +1582,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1666,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif index 5f491d2c5..4a5305958 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1491,9 +1443,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1515,9 +1465,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1539,9 +1487,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1566,9 +1512,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1593,9 +1537,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1617,9 +1559,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1641,9 +1581,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif index 16c236d2c..2dc9dc91b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clang.stack_protector.so.sarif @@ -787,9 +787,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -814,9 +812,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -847,9 +843,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -874,9 +868,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -904,9 +896,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -937,9 +927,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -967,9 +955,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1000,9 +986,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1027,9 +1011,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1057,9 +1039,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1093,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1126,9 +1104,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1153,9 +1129,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1186,9 +1160,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1213,9 +1185,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1243,9 +1213,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1270,9 +1238,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1300,9 +1266,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1333,9 +1297,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1366,9 +1328,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1390,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1414,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1438,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1462,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3030", @@ -1492,9 +1444,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1516,9 +1466,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1540,9 +1488,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1567,9 +1513,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1594,9 +1538,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1618,9 +1560,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1642,9 +1582,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1666,9 +1604,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif index bf1a95853..de42adec0 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/clangcl.pe.cpp.codeview.exe.sarif @@ -801,9 +801,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -861,9 +857,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -888,9 +882,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -912,9 +904,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -960,9 +948,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -984,9 +970,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1008,9 +992,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1032,9 +1014,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1062,9 +1042,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1086,9 +1064,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1110,9 +1086,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2001", @@ -1134,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -1161,9 +1133,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -1194,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -1221,9 +1189,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -1251,9 +1217,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -1284,9 +1248,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1314,9 +1276,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1347,9 +1307,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1374,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1404,9 +1360,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1440,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1473,9 +1425,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1500,9 +1450,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1590,9 +1534,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1623,9 +1565,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1656,9 +1596,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1680,9 +1618,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1704,9 +1640,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif index 0c4a9e366..ce00f81c7 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.default_compilation.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif index 1e92efe4e..21efb5993 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.example2.fstackprotectorstrongsspbuffersize8+fnostackprotector.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -864,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -891,9 +885,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -921,9 +913,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -954,9 +944,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -984,9 +972,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1017,9 +1003,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1044,9 +1028,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1074,9 +1056,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1110,9 +1090,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1143,9 +1121,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1170,9 +1146,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1203,9 +1177,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1230,9 +1202,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1317,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1350,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1383,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1407,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1431,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1455,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1479,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1506,9 +1458,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1533,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1557,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1581,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1605,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1677,9 +1615,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif index 98d22b0ab..4505ff73a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.sarif @@ -781,9 +781,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -808,9 +806,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -841,9 +837,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -868,9 +862,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -898,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -931,9 +921,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -961,9 +949,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -994,9 +980,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1021,9 +1005,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1051,9 +1033,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1087,9 +1067,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1120,9 +1098,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1147,9 +1123,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1180,9 +1154,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1207,9 +1179,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1237,9 +1207,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1264,9 +1232,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1294,9 +1260,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1327,9 +1291,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1360,9 +1322,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1384,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1408,9 +1366,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1432,9 +1388,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1456,9 +1410,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1480,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1504,9 +1454,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1531,9 +1479,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1558,9 +1504,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1582,9 +1526,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1606,9 +1548,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1630,9 +1570,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1660,9 +1598,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif index bff84f6ea..dc34fe47e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.execstack.so.sarif @@ -782,9 +782,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -809,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -842,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -869,9 +863,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -899,9 +891,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -932,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -962,9 +950,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -995,9 +981,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1022,9 +1006,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1052,9 +1034,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1088,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1121,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1148,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1181,9 +1155,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1238,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1295,9 +1261,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1328,9 +1292,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1361,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1385,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1409,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1433,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1457,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1481,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1559,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1583,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1607,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1631,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif index e5b18e2dc..f960deb6c 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.fortified.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif index b9025e7e8..2cde19251 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.dwo.sarif @@ -822,9 +822,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -849,9 +847,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -882,9 +878,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -909,9 +903,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -939,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -972,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1002,9 +990,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1035,9 +1021,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1062,9 +1046,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1092,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1128,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1161,9 +1139,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1188,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1221,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1248,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1278,9 +1248,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1305,9 +1273,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1335,9 +1301,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1368,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1401,9 +1363,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1425,9 +1385,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1449,9 +1407,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1476,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1503,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1527,9 +1479,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1551,9 +1501,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1575,9 +1523,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1599,9 +1545,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1623,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1647,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1677,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1701,9 +1639,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1725,9 +1661,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif index dc0daf762..8d9950746 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.gsplitdwarf.5.sarif @@ -809,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -836,9 +834,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -869,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -896,9 +890,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -926,9 +918,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -959,9 +949,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -989,9 +977,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1022,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1049,9 +1033,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1079,9 +1061,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1115,9 +1095,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1148,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1175,9 +1151,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1208,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1235,9 +1207,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1265,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1292,9 +1260,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1322,9 +1288,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1355,9 +1319,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1388,9 +1350,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1412,9 +1372,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1436,9 +1394,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1460,9 +1416,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1484,9 +1438,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1508,9 +1460,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1532,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1559,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1586,9 +1532,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3004", @@ -1610,9 +1554,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3006", @@ -1634,9 +1576,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1658,9 +1598,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1682,9 +1620,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1712,9 +1648,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif index 21d092754..9ae289069 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.4.o.no-stack-clash-protection.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -864,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -891,9 +885,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -921,9 +913,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -954,9 +944,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -984,9 +972,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1017,9 +1003,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1044,9 +1028,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1074,9 +1056,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1110,9 +1090,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1143,9 +1121,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1170,9 +1146,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1203,9 +1177,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1230,9 +1202,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1317,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1350,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1383,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1407,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1431,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1455,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1479,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1506,9 +1458,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1533,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1557,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1581,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1605,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1677,9 +1615,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif index 459c7a484..9d57a1972 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.5.o.no-stack-clash-protection.sarif @@ -805,9 +805,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -832,9 +830,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -892,9 +886,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -922,9 +914,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -955,9 +945,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -985,9 +973,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1018,9 +1004,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1045,9 +1029,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1075,9 +1057,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1111,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1144,9 +1122,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1171,9 +1147,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1204,9 +1178,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1231,9 +1203,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1261,9 +1231,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1288,9 +1256,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1318,9 +1284,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1351,9 +1315,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1384,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1408,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1432,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1456,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1480,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1507,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1534,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1558,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1582,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1606,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1654,9 +1594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif index 71d6188ac..9fdc9593e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.execstack.5.o.sarif @@ -803,9 +803,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -830,9 +828,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -863,9 +859,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -890,9 +884,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -920,9 +912,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -953,9 +943,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -983,9 +971,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1016,9 +1002,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1043,9 +1027,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1073,9 +1055,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1109,9 +1089,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1142,9 +1120,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1169,9 +1145,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1202,9 +1176,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1229,9 +1201,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1259,9 +1229,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1286,9 +1254,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1316,9 +1282,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1349,9 +1313,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1382,9 +1344,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1406,9 +1366,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1430,9 +1388,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1454,9 +1410,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1478,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1505,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1532,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1556,9 +1504,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1580,9 +1526,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1604,9 +1548,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1628,9 +1570,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1652,9 +1592,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1676,9 +1614,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1706,9 +1642,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif index a1af4303f..cf64d599b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.nodwarf.sarif @@ -786,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -813,9 +811,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -846,9 +842,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -873,9 +867,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -903,9 +895,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -936,9 +926,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -966,9 +954,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -999,9 +985,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1026,9 +1010,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1056,9 +1038,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1092,9 +1072,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1125,9 +1103,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1152,9 +1128,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1185,9 +1159,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1212,9 +1184,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1242,9 +1212,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1269,9 +1237,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1299,9 +1265,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1332,9 +1296,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1365,9 +1327,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1389,9 +1349,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1413,9 +1371,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1437,9 +1393,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1461,9 +1415,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1485,9 +1437,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1509,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1536,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1563,9 +1509,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1587,9 +1531,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1611,9 +1553,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1635,9 +1575,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1665,9 +1603,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif index 3c828b129..f5b8ac7a4 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.helloworld.noexecstack.5.o.sarif @@ -805,9 +805,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -832,9 +830,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -892,9 +886,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -922,9 +914,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -955,9 +945,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -985,9 +973,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1018,9 +1004,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1045,9 +1029,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1075,9 +1057,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1111,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1144,9 +1122,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1171,9 +1147,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1204,9 +1178,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1231,9 +1203,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1261,9 +1231,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1288,9 +1256,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1318,9 +1284,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1351,9 +1315,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1384,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1408,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1432,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1456,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1480,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1507,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1534,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1558,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1582,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1606,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1654,9 +1594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif index aa06601e2..a0c7aa7f8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.immediate_binding.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif index ec7218504..35217331f 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_fortification_required.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif index 00169bfdc..4ab87a2ac 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_immediate_binding.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif index 76e30e0e0..4dcda324a 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.no_stack_protector.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif index 26a2ec96b..e6498d366 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif index db5a7a2ee..47a394dca 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.noexecstack.so.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif index 70aa2d308..38e30ada3 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.non_pie_executable.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif index a352562a4..dc36e1ebe 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.dbg.sarif @@ -822,9 +822,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -849,9 +847,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -882,9 +878,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -909,9 +903,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -939,9 +931,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -972,9 +962,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -1002,9 +990,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1035,9 +1021,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1062,9 +1046,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1092,9 +1074,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1128,9 +1108,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1161,9 +1139,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1188,9 +1164,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1221,9 +1195,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1248,9 +1220,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1278,9 +1248,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1305,9 +1273,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1335,9 +1301,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1368,9 +1332,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1401,9 +1363,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1425,9 +1385,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1449,9 +1407,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1476,9 +1432,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1503,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1527,9 +1479,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1551,9 +1501,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1575,9 +1523,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1599,9 +1545,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1623,9 +1567,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1647,9 +1589,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1677,9 +1617,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1701,9 +1639,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1725,9 +1661,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif index cafef0877..f5692be5b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.objcopy.stripall.addgnudebuglink.sarif @@ -782,9 +782,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -809,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -842,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -869,9 +863,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -899,9 +891,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -932,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -962,9 +950,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -995,9 +981,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1022,9 +1006,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1052,9 +1034,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1088,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1121,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1148,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1181,9 +1155,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1238,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1295,9 +1261,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1328,9 +1292,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1361,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1385,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1409,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1433,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1457,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1484,9 +1436,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1511,9 +1461,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1535,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1559,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1583,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1607,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1631,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif index 1b735753c..2b889b4af 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.object_file.o.sarif @@ -798,9 +798,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -825,9 +823,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -858,9 +854,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -885,9 +879,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -915,9 +907,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -948,9 +938,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -978,9 +966,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1011,9 +997,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1038,9 +1022,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1068,9 +1050,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1104,9 +1084,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1137,9 +1115,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1164,9 +1140,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1197,9 +1171,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1224,9 +1196,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1254,9 +1224,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1281,9 +1249,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1311,9 +1277,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1344,9 +1308,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1377,9 +1339,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1401,9 +1361,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1425,9 +1383,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3001", @@ -1452,9 +1408,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1479,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1503,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1527,9 +1477,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1551,9 +1499,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1575,9 +1521,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1599,9 +1543,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1677,9 +1615,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif index 73b08fdae..de066311b 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pe.objectivec.dwarf.exe.sarif @@ -564,9 +564,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -594,9 +592,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -627,9 +623,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -657,9 +651,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -684,9 +676,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -708,9 +698,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -732,9 +720,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -756,9 +742,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -780,9 +764,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -804,9 +786,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -828,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -858,9 +836,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" }, { "id": "BA5001", @@ -882,9 +858,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -906,9 +880,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA2005", @@ -933,9 +905,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -966,9 +936,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -993,9 +961,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1029,9 +995,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1056,9 +1020,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1086,9 +1048,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1113,9 +1073,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1143,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1176,9 +1132,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif index 9d2d81f2c..7a31b65dd 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.pie_executable.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif index 198bdb5ab..129304a9e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsro.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif index b3496781a..71ffc0b1e 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.relocationsrw.sarif @@ -782,9 +782,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -809,9 +807,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -842,9 +838,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -869,9 +863,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -899,9 +891,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -932,9 +922,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -962,9 +950,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -995,9 +981,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1022,9 +1006,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1052,9 +1034,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1088,9 +1068,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1121,9 +1099,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1148,9 +1124,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1181,9 +1155,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1208,9 +1180,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1238,9 +1208,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1265,9 +1233,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1295,9 +1261,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1328,9 +1292,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1361,9 +1323,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1385,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1409,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1433,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1457,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1481,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1505,9 +1455,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1532,9 +1480,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1559,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1583,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1607,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1631,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1661,9 +1599,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif index 931a64434..50d43532d 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.4.o.sarif @@ -804,9 +804,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -831,9 +829,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -864,9 +860,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -891,9 +885,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -921,9 +913,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -954,9 +944,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -984,9 +972,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1017,9 +1003,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1044,9 +1028,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1074,9 +1056,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1110,9 +1090,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1143,9 +1121,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1170,9 +1146,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1203,9 +1177,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1230,9 +1202,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1260,9 +1230,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1287,9 +1255,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1317,9 +1283,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1350,9 +1314,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1383,9 +1345,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1407,9 +1367,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1431,9 +1389,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1455,9 +1411,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1479,9 +1433,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1506,9 +1458,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1533,9 +1483,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1557,9 +1505,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1581,9 +1527,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1605,9 +1549,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1629,9 +1571,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1653,9 +1593,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1677,9 +1615,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1707,9 +1643,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif index 075b1de8a..16028c0e8 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.requiredsymbol.5.o.sarif @@ -805,9 +805,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -832,9 +830,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -865,9 +861,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -892,9 +886,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -922,9 +914,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -955,9 +945,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -985,9 +973,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -1018,9 +1004,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1045,9 +1029,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1075,9 +1057,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1111,9 +1091,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1144,9 +1122,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1171,9 +1147,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1204,9 +1178,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1231,9 +1203,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1261,9 +1231,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1288,9 +1256,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1318,9 +1284,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1351,9 +1315,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1384,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1408,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1432,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA5001", @@ -1456,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1480,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1507,9 +1459,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1534,9 +1484,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3003", @@ -1558,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3004", @@ -1582,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "GenerateRequiredSymbolFormat", - "guid": null + "name": "GenerateRequiredSymbolFormat" }, { "id": "BA3005", @@ -1606,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA3006", @@ -1630,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1654,9 +1594,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1678,9 +1616,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1708,9 +1644,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif index f88dafd66..988b54661 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.shared_library.so.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif index 18e78bdcc..03618d784 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif index c931c9ad0..60341f525 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.stack_protector.so.sarif @@ -784,9 +784,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -811,9 +809,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -844,9 +840,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -871,9 +865,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -901,9 +893,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -934,9 +924,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -964,9 +952,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -997,9 +983,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1024,9 +1008,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1054,9 +1036,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1090,9 +1070,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1123,9 +1101,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1150,9 +1126,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1183,9 +1157,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1210,9 +1182,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1240,9 +1210,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1267,9 +1235,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1297,9 +1263,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1330,9 +1294,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1363,9 +1325,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1387,9 +1347,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1411,9 +1369,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1435,9 +1391,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1459,9 +1413,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1483,9 +1435,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1507,9 +1457,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1534,9 +1482,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1561,9 +1507,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1585,9 +1529,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1609,9 +1551,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1633,9 +1573,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1663,9 +1601,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { diff --git a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif index 85b8b4821..abecdfb73 100644 --- a/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif +++ b/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestsData/Expected/gcc.unfortified.sarif @@ -783,9 +783,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "LoadImageAboveFourGigabyteAddress", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "FourGbCheck" } @@ -810,9 +808,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotIncorporateVulnerableDependencies", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ATLVersionCheck" } @@ -843,9 +839,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSecureSourceCodeHashing", - "guid": null + "name": "EnableSecureSourceCodeHashing" }, { "id": "BA2005", @@ -870,9 +864,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotShipVulnerableBinaries", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "BinaryVersionsCheck" } @@ -900,9 +892,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "BuildWithSecureTools", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerVersionCheck" } @@ -933,9 +923,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableCriticalCompilerWarnings", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "CompilerWarningsCheck" } @@ -963,9 +951,7 @@ "text": "'{0}' is a kernel mode portable executable compiled for a version of Windows that does not support the control flow guard feature for kernel mode binaries." } }, - "shortDescription": null, "name": "EnableControlFlowGuard", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ControlFlowGuardCheck" } @@ -996,9 +982,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableAddressSpaceLayoutRandomization", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DBCheck" } @@ -1023,9 +1007,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkImportsSectionAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "ExecutableImportsCheck" } @@ -1053,9 +1035,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSCheck" } @@ -1089,9 +1069,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotModifyStackProtectionCookie", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "DefaultGSCookieCheck" } @@ -1122,9 +1100,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "InitializeStackProtection", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFriendlyInitCheck" } @@ -1149,9 +1125,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotDisableStackProtectionForFunctions", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "GSFunctionSafeBuffersCheck" } @@ -1182,9 +1156,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableHighEntropyVirtualAddresses", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "HighEntropyVACheck" } @@ -1209,9 +1181,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "MarkImageAsNXCompatible", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "NXCheck" } @@ -1239,9 +1209,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "EnableSafeSEH", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SafeSEHCheck" } @@ -1266,9 +1234,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsShared", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "SharedSectionCheck" } @@ -1296,9 +1262,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, "name": "DoNotMarkWritableSectionsAsExecutable", - "guid": null, "properties": { "equivalentBinScopeRuleReadableName": "WXCheck" } @@ -1329,9 +1293,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "SignSecurely", - "guid": null + "name": "SignSecurely" }, { "id": "BA2024", @@ -1362,9 +1324,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableSpectreMitigations", - "guid": null + "name": "EnableSpectreMitigations" }, { "id": "BA2025", @@ -1386,9 +1346,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableShadowStack", - "guid": null + "name": "EnableShadowStack" }, { "id": "BA2026", @@ -1410,9 +1368,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableAdditionalSdlSecurityChecks", - "guid": null + "name": "EnableAdditionalSdlSecurityChecks" }, { "id": "BA3003", @@ -1434,9 +1390,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackProtector", - "guid": null + "name": "EnableStackProtector" }, { "id": "BA3005", @@ -1458,9 +1412,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableStackClashProtection", - "guid": null + "name": "EnableStackClashProtection" }, { "id": "BA5001", @@ -1482,9 +1434,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutableMachO", - "guid": null + "name": "EnablePositionIndependentExecutableMachO" }, { "id": "BA5002", @@ -1506,9 +1456,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotAllowExecutableStack", - "guid": null + "name": "DoNotAllowExecutableStack" }, { "id": "BA3001", @@ -1533,9 +1481,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnablePositionIndependentExecutable", - "guid": null + "name": "EnablePositionIndependentExecutable" }, { "id": "BA3002", @@ -1560,9 +1506,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "DoNotMarkStackAsExecutable", - "guid": null + "name": "DoNotMarkStackAsExecutable" }, { "id": "BA3006", @@ -1584,9 +1528,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableNonExecutableStack", - "guid": null + "name": "EnableNonExecutableStack" }, { "id": "BA3010", @@ -1608,9 +1550,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableReadOnlyRelocations", - "guid": null + "name": "EnableReadOnlyRelocations" }, { "id": "BA3011", @@ -1632,9 +1572,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "EnableBindNow", - "guid": null + "name": "EnableBindNow" }, { "id": "BA3030", @@ -1662,9 +1600,7 @@ "text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." } }, - "shortDescription": null, - "name": "UseCheckedFunctionsWithGcc", - "guid": null + "name": "UseCheckedFunctionsWithGcc" } ], "properties": { From b542a26da085601eafba715791ad2bce483d9c5a Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Sat, 8 Jan 2022 19:06:54 -0800 Subject: [PATCH 07/10] move && to end of line --- src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs index c8dc7fd81..098e149a1 100644 --- a/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs +++ b/src/BinSkim.Rules/PERules/BA2006.BuildWithSecureTools.cs @@ -116,8 +116,8 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte Symbol om = omView.Value; ObjectModuleDetails omDetails = om.GetObjectModuleDetails(); - if (omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftC - && omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftCxx) + if (omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftC && + omDetails.WellKnownCompiler != WellKnownCompilers.MicrosoftCxx) { // TODO: MikeFan (1/6/2022) // We need to take a step back and comprehensively review our compiler/language support. From 9d58f42be5d18c77cb4976a7403265ba4a5ad0e1 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Mon, 10 Jan 2022 11:56:14 -0800 Subject: [PATCH 08/10] upgrade submodule --- src/sarif-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sarif-sdk b/src/sarif-sdk index 744f7206b..4959f73eb 160000 --- a/src/sarif-sdk +++ b/src/sarif-sdk @@ -1 +1 @@ -Subproject commit 744f7206b6d51bf3a285ce2cb80d90e7d1b942f2 +Subproject commit 4959f73ebe231caa914931a9f26699a9b3dd4315 From b32a98290a0acbd529f3019647c2d42dcff3be37 Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:08:56 -0800 Subject: [PATCH 09/10] update history.md --- src/ReleaseHistory.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReleaseHistory.md b/src/ReleaseHistory.md index 96056700d..fc8c8a09a 100644 --- a/src/ReleaseHistory.md +++ b/src/ReleaseHistory.md @@ -2,7 +2,7 @@ ## Unreleased -* BUGFIX: Fix Error BA2006: '...' was compiled with one or more modules which were not built using minimum required tool versions [533](https://github.com/microsoft/binskim/pull/533) +* BUGFIX: Fix Error BA2006: '...' was compiled with one or more modules which were not built using minimum required tool versions [545](https://github.com/microsoft/binskim/pull/545) * BUGFIX: Fix `JsonSerializationException` that occurs when saving SARIF v1 with telemetry enabled. [#535](https://github.com/microsoft/binskim/pull/535) * BUGFIX: Fix `NullReferenceException` when `--Hashes` and telemetry rules are enabled. [#531](https://github.com/microsoft/binskim/pull/531) From 3441b727f0d616f9e828e785e9e5f314a9db363f Mon Sep 17 00:00:00 2001 From: Shaopeng <81775155+shaopeng-gh@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:44:11 -0800 Subject: [PATCH 10/10] update history md file --- src/ReleaseHistory.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReleaseHistory.md b/src/ReleaseHistory.md index fc8c8a09a..fde4e9095 100644 --- a/src/ReleaseHistory.md +++ b/src/ReleaseHistory.md @@ -2,7 +2,7 @@ ## Unreleased -* BUGFIX: Fix Error BA2006: '...' was compiled with one or more modules which were not built using minimum required tool versions [545](https://github.com/microsoft/binskim/pull/545) +* BUGFIX: Fix incorrect analysis for non-Microsoft compiler on BA2006.BuildWithSecureTools [545](https://github.com/microsoft/binskim/pull/545) * BUGFIX: Fix `JsonSerializationException` that occurs when saving SARIF v1 with telemetry enabled. [#535](https://github.com/microsoft/binskim/pull/535) * BUGFIX: Fix `NullReferenceException` when `--Hashes` and telemetry rules are enabled. [#531](https://github.com/microsoft/binskim/pull/531)

hA8T>#iK_HLk|#{h2SfZ#1lagUyV)6~*o^&uclJ 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 zÂ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�#Cm%P{WI_R$Wt(a8 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ℑu(vXL87!BZcI3pBs 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%0A~YKgqnTKJ%^3%XG|(G|!iGddB0;(~U@TpE=z! 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

J1gXR#MD`oH0hnW8OiV{c~T`E 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